diff --git a/.gitignore b/.gitignore
index 093cad2..a51fd68 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,17 +1,9 @@
-## Ignore Visual Studio temporary files, build results, and
-## files generated by popular Visual Studio add-ons.
-##
-## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
-
# User-specific files
*.suo
*.user
*.userosscache
*.sln.docstates
-# User-specific files (MonoDevelop/Xamarin Studio)
-*.userprefs
-
# Build results
[Dd]ebug/
[Dd]ebugPublic/
@@ -23,8 +15,6 @@ bld/
# Visual Studio 2015 cache/options directory
.vs/
-# Uncomment if you have tasks that create the project's static files in wwwroot
-#wwwroot/
# MSTest test Results
[Tt]est[Rr]esult*/
@@ -283,3 +273,7 @@ __pycache__/
*.btm.cs
*.odx.cs
*.xsd.cs
+
+# Exclude build but include storage dir
+src/bin/net8.0-windows/runtimes
+src/bin/net8.0-windows/*.*
diff --git a/FUNDING.yml b/FUNDING.yml
new file mode 100644
index 0000000..a48c283
--- /dev/null
+++ b/FUNDING.yml
@@ -0,0 +1 @@
+github: robinrodricks
diff --git a/README.md b/README.md
index 55876b0..72ab4ab 100644
--- a/README.md
+++ b/README.md
@@ -1,74 +1,180 @@

-SharpBrowser is the fastest open source C# web browser there is! Slightly faster than Google Chrome when rendering web pages due to lightweight CEF renderer. We compared every available .NET browsing browsing engine and finally settled on the high-performance [CefSharp](https://github.com/cefsharp/CefSharp/). Released under the permissive MIT license.
+SharpBrowser is the fastest and most full-featured open source C# web browser there is! Slightly faster than Google Chrome when rendering web pages due to lightweight CEF renderer. We compared every available .NET browsing engine and finally settled on the high-performance [CefSharp](https://github.com/cefsharp/CefSharp/). Released under the permissive MIT license.
## Features
-- HTML5, CSS3, JS, HTML5 Video, WebGL 3D, etc
-- Tabbed browsing
-- Address bar (also opens Google)
-- Back, Forward, Stop, Refresh
-- Developer tools
+
+
+### Modern
+
+- [HTML5, CSS3, JS, Video, PDF, WebGL, WebAssembly, WebRTC, WebMIDI](#screenshots)
+- Tabbed browsing with website favicons
+- Address bar (also opens Google or any search engine)
+- Back, Forward, Stop, Refresh, Home, Menu button
+- Print and Print to PDF
- Search bar (also highlights all instances)
-- Download manager
+- File downloads and download manager
+- View online & offline webpages
+- Fullscreen mode
+
+### Smart
+
+- [Hotkeys for all features](#hotkeys)
+- Saves open tabs and resumes the browsing session when reopened
+- Saves cookies and web cache in the `AppData` folder
+- Saves application settings in a custom JSON file
+- Saves favicons in a disk cache for fast reuse
+- Developer tools
+- Web app permission handling
+- Popups open in new tabs
+
+### Extensible
+
+- [Easily add your own branding, styling, buttons or hotkeys](#customization)
- Custom error pages
- Custom context menu
-- Easily add vendor-specific branding, buttons or hotkeys
-- View online & offline webpages
+- Custom application main menu
+- Custom settings
+- Custom installer package using InnoSetup
## Hotkeys
Hotkeys | Function
------------ | -------------
+Ctrl+MouseWheel | Zoom in/out
Ctrl+T | Add a new tab
-Ctrl+N | Add a new window
Ctrl+W | Close active tab
+Ctrl+MiddleClick | Close Tab
F5 | Refresh active tab
+F11 | Toggle fullscreen
F12 | Open developer tools
Ctrl+Tab | Switch to the next tab
Ctrl+Shift+Tab | Switch to the previous tab
Ctrl+F | Open search bar (Enter to find next, Esc to close)
+Ctrl+P | Print
+Ctrl+Shift+P | Print to PDF
-## Code
-- SharpBrowser uses CefSharp 71, NET Framework 4.6
-- `MainForm.cs` - main web browser UI and related functionality
-- `Handlers` - various handlers that we have registered with CefSharp that enable deeper integration between us and CefSharp
-- `Data/JSON.cs` - fast JSON serializer/deserializer
-- `bin` - Binaries are included in the `bin` folder due to the complex CefSharp setup required. Don't empty this folder.
-- `bin/storage` - HTML and JS required for downloads manager and custom error pages
-## Credits
+## Documentation
-- [Robin Rodricks](https://github.com/robinrodricks) - SharpBrowser project.
-- [Alex Maitland](https://github.com/amaitland) - CefSharp project, wrapper for CEF embeddable browser.
-- [Ahmet Uzun](https://github.com/postacik) - Original browser project.
+- See the [Compilation Guide](docs/Compilation.md) for steps to get started.
+- See the [Distribution Guide](docs/Distribution.md) to create a custom setup installer.
+
+
+### System requirements
+
+- You need .NET 8 on Windows 64-bit.
+
+- You need [VC++ 2019 Runtime](https://aka.ms/vs/17/release/vc_redist.x64.exe) (64-bit)
+- You might need [VC++ 2017 Runtime](https://www.microsoft.com/en-in/download/details.aspx?id=48145) (64-bit)
+
+- You need to install the version of VC++ Runtime that CEFSharp needs. As per our CefSharp version, according to [this](https://github.com/cefsharp/CefSharp/#release-branches), we need the above versions
-## Screenshots
-### Apple Homepage
+### Customization
-
+- To customize the browser branding, name, URL, default search engine, default proxy, modify the `BrowserConfig` class.
-### Google Maps
+- To customize the application icon, change `sharpbrowser.ico` inside the `Resources` folder.
-
+- To customize the tab size and tab colors, modify the `BrowserTabStyle` class.
-### Search Bar
+- To enable or disable Web Camera, Microphone, Javascript, WebGL, WebRTC, WebMIDI, LocalStorage, modify the `BrowserConfig` class.
-
+- To register hotkeys for your own commands, modify the `HotkeyManager` class.
-### Downloads Tab
+- To register your own commands into the main menu, open the form designed for `MainForm` and click the `MainMenu` object. Add `IconMenuItem` objects into that menu.
-
+- To register your own commands into the page context-menu, modify `ContextMenuHandler.OnBeforeContextMenu` function, and then implement the command inside `ContextMenuHandler.OnContextMenuCommand`.
-### Developer Tools
+- To setup how web app permissions are handled, modify `PermissionHandler.OnShowPermissionPrompt` (some flags are already inside `BrowserConfig` and can easily be changed).
-
+- To add new settings saved in the JSON file, simply call `ConfigManager.Get*` and `ConfigManager.Set` anywhere in your code. It will save into the file automatically.
-### Custom Error Pages
-
+### Code
-
+- SharpBrowser uses CefSharp 134 and is built on NET.
+- SharpBrowser only supports Windows x64 platform.
+- `MainForm.cs` - main web browser UI and related functionality
+- `Managers` - classes that manage various types of browsing functionality, like settings, downloads and hotkeys
+- `Handlers` - various handlers that we have registered with CefSharp that enable deeper integration between us and CefSharp
+- `bin` - Binaries are included in the `bin` folder due to the complex CefSharp setup required. Don't empty this folder.
+- `bin/storage` - HTML and JS required for downloads manager and custom error pages
+
+## Screenshots
+
\ No newline at end of file
diff --git a/docs/Compilation.md b/docs/Compilation.md
new file mode 100644
index 0000000..abd8ee7
--- /dev/null
+++ b/docs/Compilation.md
@@ -0,0 +1,31 @@
+# How to compile SharpBrowser
+
+#### Step 1: Fork sharpbrowser
+
+Fork the sharpbrowser repository on GitHub.
+
+
+
+#### Step 2: Install Visual Studio
+
+Download Visual Studio Community with the "Desktop development with .NET" component
+
+
+
+#### Step 2: Setup this project in VS
+
+Open VS Community and select "Clone a repository"
+
+
+
+#### Step 3: Clone this project
+
+Type in your sharpbrowser fork URL and press "Clone"
+
+
+
+#### Step 4: Develop!
+
+You now have a copy of SharpBrowser! Press "Start" after you choose the system architecture
+
+
diff --git a/docs/Distribution.md b/docs/Distribution.md
new file mode 100644
index 0000000..bacac66
--- /dev/null
+++ b/docs/Distribution.md
@@ -0,0 +1,27 @@
+# How to distribute SharpBrowser with your own branding
+
+#### Step 1: Clone the source
+
+Create a Github clone of SharpBrowser using [our tutorial](Compilation.md).
+
+#### Step 2: Open BrowserConfig.cs
+
+Open the Solution explorer, and navigate to `Model > BrowserConfig.cs`.
+
+
+
+#### Step 3: Edit the configuration strings
+
+
+
+#### Step 4: Compile the application
+
+Make sure you select `Release` mode and then compile the application using the Build or Start button.
+
+
+
+#### Step 5: Create a new installer package
+To recreate the setup file, install [InnoSetup](https://jrsoftware.org/isinfo.php) and run the InnoSetup script in the `setup` folder.
+
+#### Step 6: Share your installer package
+Share the newly generated installer package with your friends!
\ No newline at end of file
diff --git a/docs/Users.md b/docs/Users.md
new file mode 100644
index 0000000..6b38edc
--- /dev/null
+++ b/docs/Users.md
@@ -0,0 +1,5 @@
+# How to use SharpBrowser
+
+Simply run the executable `SharpBrowserSetup.exe` and it should install.
+
+This only works on Windows.
diff --git a/images/1.png b/images/1.png
deleted file mode 100644
index 90feea7..0000000
Binary files a/images/1.png and /dev/null differ
diff --git a/images/2.png b/images/2.png
deleted file mode 100644
index c82a5f1..0000000
Binary files a/images/2.png and /dev/null differ
diff --git a/images/3.png b/images/3.png
deleted file mode 100644
index df18b9c..0000000
Binary files a/images/3.png and /dev/null differ
diff --git a/images/4.png b/images/4.png
deleted file mode 100644
index fabc540..0000000
Binary files a/images/4.png and /dev/null differ
diff --git a/images/apple.png b/images/apple.png
new file mode 100644
index 0000000..fef6d49
Binary files /dev/null and b/images/apple.png differ
diff --git a/images/devtools.png b/images/devtools.png
new file mode 100644
index 0000000..4785e13
Binary files /dev/null and b/images/devtools.png differ
diff --git a/images/downloads.png b/images/downloads.png
new file mode 100644
index 0000000..86e71e4
Binary files /dev/null and b/images/downloads.png differ
diff --git a/images/error1.png b/images/error1.png
index 72ec9ce..4b1b46f 100644
Binary files a/images/error1.png and b/images/error1.png differ
diff --git a/images/error2.png b/images/error2.png
index 568bb12..dc0953e 100644
Binary files a/images/error2.png and b/images/error2.png differ
diff --git a/images/googlemaps.png b/images/googlemaps.png
new file mode 100644
index 0000000..bf32143
Binary files /dev/null and b/images/googlemaps.png differ
diff --git a/images/logo3.png b/images/logo3.png
index ec6c401..198c799 100644
Binary files a/images/logo3.png and b/images/logo3.png differ
diff --git a/images/mainmenu.png b/images/mainmenu.png
new file mode 100644
index 0000000..aae81eb
Binary files /dev/null and b/images/mainmenu.png differ
diff --git a/images/pdf.png b/images/pdf.png
new file mode 100644
index 0000000..67906ed
Binary files /dev/null and b/images/pdf.png differ
diff --git a/images/search.png b/images/search.png
index 5759e85..41e44d0 100644
Binary files a/images/search.png and b/images/search.png differ
diff --git a/images/topbar.png b/images/topbar.png
new file mode 100644
index 0000000..b587ff8
Binary files /dev/null and b/images/topbar.png differ
diff --git a/images/wasm.png b/images/wasm.png
new file mode 100644
index 0000000..ccb4286
Binary files /dev/null and b/images/wasm.png differ
diff --git a/images/webcam.png b/images/webcam.png
new file mode 100644
index 0000000..d6969d0
Binary files /dev/null and b/images/webcam.png differ
diff --git a/images/webgl.png b/images/webgl.png
new file mode 100644
index 0000000..a3099de
Binary files /dev/null and b/images/webgl.png differ
diff --git a/images/webmidi.png b/images/webmidi.png
new file mode 100644
index 0000000..af186c9
Binary files /dev/null and b/images/webmidi.png differ
diff --git a/images/youtube.png b/images/youtube.png
new file mode 100644
index 0000000..5d71754
Binary files /dev/null and b/images/youtube.png differ
diff --git a/setup/InnoSetupScript.iss b/setup/InnoSetupScript.iss
new file mode 100644
index 0000000..0f8f6ce
--- /dev/null
+++ b/setup/InnoSetupScript.iss
@@ -0,0 +1,50 @@
+; Script generated by the Inno Setup Script Wizard.
+; SEE THE DOCUMENTATION FOR DETAILS ON CREATING INNO SETUP SCRIPT FILES!
+
+#define MyAppName "SharpBrowser"
+#define MyAppVersion "1.0"
+#define MyAppPublisher "SharpBrowser"
+#define MyAppURL "https://github.com/sharpbrowser/SharpBrowser/"
+#define MyAppExeName "SharpBrowser.exe"
+
+[Setup]
+; NOTE: The value of AppId uniquely identifies this application. Do not use the same AppId value in installers for other applications.
+; (To generate a new GUID, click Tools | Generate GUID inside the IDE.)
+AppId={{3301F22D-5C60-4FF2-B307-6B5696204707}
+AppName={#MyAppName}
+AppVersion={#MyAppVersion}
+;AppVerName={#MyAppName} {#MyAppVersion}
+AppPublisher={#MyAppPublisher}
+AppPublisherURL={#MyAppURL}
+AppSupportURL={#MyAppURL}
+AppUpdatesURL={#MyAppURL}
+DefaultDirName={autopf}\{#MyAppName}
+DisableProgramGroupPage=yes
+LicenseFile=D:\Github\SharpBrowser\LICENSE
+; Uncomment the following line to run in non administrative install mode (install for current user only.)
+;PrivilegesRequired=lowest
+OutputDir=D:\Github\SharpBrowser\setup
+OutputBaseFilename=SharpBrowserSetup
+SetupIconFile=D:\Github\SharpBrowser\src\Resources\sharpbrowser.ico
+Compression=lzma
+SolidCompression=yes
+WizardStyle=modern
+
+[Languages]
+Name: "english"; MessagesFile: "compiler:Default.isl"
+
+[Tasks]
+Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: unchecked
+
+[Files]
+Source: "D:\Github\SharpBrowser\src\bin\{#MyAppExeName}"; DestDir: "{app}"; Flags: ignoreversion
+Source: "D:\Github\SharpBrowser\src\bin\*"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs createallsubdirs
+; NOTE: Don't use "Flags: ignoreversion" on any shared system files
+
+[Icons]
+Name: "{autoprograms}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"
+Name: "{autodesktop}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"; Tasks: desktopicon
+
+[Run]
+Filename: "{app}\{#MyAppExeName}"; Description: "{cm:LaunchProgram,{#StringChange(MyAppName, '&', '&&')}}"; Flags: nowait postinstall skipifsilent
+
diff --git a/src/App.config b/src/App.config
index e8419f3..aa9ced9 100644
--- a/src/App.config
+++ b/src/App.config
@@ -1,10 +1,5 @@
-
-
-
-
-
-
+
diff --git a/src/Config/BrowserConfig.cs b/src/Config/BrowserConfig.cs
new file mode 100644
index 0000000..ca5e6ce
--- /dev/null
+++ b/src/Config/BrowserConfig.cs
@@ -0,0 +1,193 @@
+using CefSharp;
+using CefSharp.WinForms;
+using System.Net;
+
+namespace SharpBrowser.Config {
+ internal static class BrowserConfig {
+
+ ///
+ /// The title of the window and application in Windows.
+ ///
+ public static string Branding = "SharpBrowser";
+ ///
+ /// The folder name in AppData.
+ ///
+ public static string AppID = "SharpBrowser";
+ ///
+ /// The language you distribute it in
+ ///
+ public static string AcceptLanguage = "en-US,en;q=0.9";
+ ///
+ /// The browser's user agent string, which identifies itself to websites
+ ///
+ public static string UserAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.5112.102 Safari/537.36 CefSharp/" + Cef.CefSharpVersion; // UserAgent to fix issue with Google account authentication
+ ///
+ /// The home page of your browser which shows up when you press the home button
+ ///
+ public static string HomepageURL = "https://www.google.com";
+ ///
+ /// The page you will see when you press "New Tab".
+ ///
+ public static string NewTabURL = "about:blank";
+ ///
+ /// The main URL prefix for internal pages.
+ ///
+ public static string InternalScheme = "sharpbrowser";
+ ///
+ /// The URL for the downloads page
+ ///
+ public static string DownloadsURL = InternalScheme + "://storage/downloads.html";
+ ///
+ /// URL to display when local file is not fonud
+ ///
+ public static string FileNotFoundURL = InternalScheme + "://storage/errors/notFound.html";
+ ///
+ /// URL to display when internet connection is not available.
+ ///
+ public static string CannotConnectURL = InternalScheme + "://storage/errors/cannotConnect.html";
+ ///
+ /// The search string; it must be the string before the search result.
+ /// Examples:
+ /// https://www.google.com/search?q=
+ /// https://www.bing.com/search?q=
+ /// https://duckduckgo.com/?q=
+ ///
+ public static string SearchURL = "https://www.google.com/search?q=";
+
+
+
+ ///
+ /// Should we save the tabs that are open and re-open them on the next startup?
+ ///
+ public static bool SaveOpenTabs = true;
+ ///
+ /// Is WebGL enabled for webpages?
+ ///
+ public static bool WebGL = true;
+ ///
+ /// Can JS on webpages access WebRTC streams?
+ ///
+ public static bool WebRTC = true;
+ ///
+ /// Can JS on webpages access MIDI devices using WebMidi API?
+ ///
+ public static bool WebMidi = true;
+ ///
+ /// Can JS on webpages access Web Cameras?
+ ///
+ public static bool Camera = true;
+ ///
+ /// Can JS on webpages access Microphone?
+ ///
+ public static bool Microphone = true;
+ ///
+ /// Is JS enabled for webpages?
+ ///
+ public static bool Javascript = true;
+ ///
+ /// Can JS on webpages access the clipboard?
+ ///
+ public static bool JavascriptClipboard = true;
+ ///
+ /// Can webpages access local files?
+ ///
+ public static bool LocalFiles = false;
+ ///
+ /// Can webpages access local storage API?
+ ///
+ public static bool LocalStorage = true;
+ ///
+ /// Can users resize text areas on webpages?
+ ///
+ public static bool TextAreaResize = true;
+
+
+ //3way to set proxy, needs enum to reduce complication.
+ public static ProxyMode currentProxyMode = ProxyMode.AutoDetect;
+ //public static bool useSystemProxy = true;
+
+ ///
+ /// If true then the following proxy is used for all browsing and downloads.
+ ///
+ //public static bool customProxy = false;
+ public static string ProxyIP = "123.123.123.123";
+ public static int ProxyPort = 123;
+ public static string ProxyUsername = "username";
+ public static string ProxyPassword = "pass";
+ public static string ProxyBypassList = "";
+
+ public enum ProxyMode
+ {
+ ///
+ /// aka use system proxy
+ ///
+ AutoDetect,
+ CustomProxy,
+ NoProxy,
+ }
+
+ ///
+ /// Load the above config into the CEF `BrowserSettings` object.
+ ///
+ public static BrowserSettings GetCefConfig() {
+ BrowserSettings config = new BrowserSettings();
+
+ config.TextAreaResize = TextAreaResize.ToCefState();
+ config.LocalStorage = LocalStorage.ToCefState();
+ config.WebGl = WebGL.ToCefState();
+ config.Javascript = Javascript.ToCefState();
+ config.JavascriptAccessClipboard = JavascriptClipboard.ToCefState();
+ config.JavascriptCloseWindows = CefState.Disabled;
+ config.JavascriptDomPaste = JavascriptClipboard.ToCefState();
+ config.RemoteFonts = CefState.Enabled;
+
+ return config;
+ }
+ public static CefState ToCefState(this bool value) {
+ return value ? CefState.Enabled : CefState.Disabled;
+ }
+
+ ///
+ /// Load the above config into the CEF `CefSettings` object.
+ ///
+ public static void GetCefSettings(CefSettings settings) {
+
+ // add user agent settings
+ settings.UserAgent = UserAgent;
+ settings.AcceptLanguageList = AcceptLanguage;
+ settings.IgnoreCertificateErrors = true;
+
+ // needed for loading local images
+ if (LocalFiles) {
+ settings.CefCommandLineArgs.Add("disable-web-security", "1");
+ settings.CefCommandLineArgs.Add("allow-file-access-from-files", "1");
+ }
+
+ // enable webRTC streams
+ if (WebRTC) {
+ settings.CefCommandLineArgs.Add("enable-media-stream", "1");
+ }
+
+ if (currentProxyMode == ProxyMode.AutoDetect)
+ {
+ //settings.CefCommandLineArgs.Add("proxy-auto-detect"); // or maybe do nothing.
+ }
+ else if (currentProxyMode == ProxyMode.CustomProxy)
+ {
+ // enable proxy if wanted
+ CefSharpSettings.Proxy = new ProxyOptions(
+ ProxyIP,
+ ProxyPort.ToString(),
+ ProxyUsername,ProxyPassword,
+ ProxyBypassList);
+ }
+ else if (currentProxyMode == ProxyMode.NoProxy)
+ {
+
+ // disable proxy if not wanted
+ settings.CefCommandLineArgs.Add("no-proxy-server");
+ }
+ }
+
+ }
+}
diff --git a/src/Config/BrowserTabStyle.cs b/src/Config/BrowserTabStyle.cs
new file mode 100644
index 0000000..196cd3b
--- /dev/null
+++ b/src/Config/BrowserTabStyle.cs
@@ -0,0 +1,36 @@
+using System.Drawing;
+
+namespace SharpBrowser.Config {
+ internal static class BrowserTabStyle {
+
+ // Tab styles
+
+ public static int TabHeight = 40;
+ public static int TabLeftPadding = 10;
+
+ public static int TabCloseButton_XOffset = 28;
+ public static int TabButton_Y = 10;
+ public static int Tab_IconSize = 16;
+
+ public static Color TabBackColor_Rollover = Color.LightGray;
+ public static Color TabBackColor_Selected = Color.FromArgb(255, 255, 255);
+ public static Color TabBackColor_Normal = Color.FromArgb(225, 225, 225);
+
+ public static SolidBrush BackColor = new SolidBrush(TabBackColor_Normal);
+
+ public static Color TabBorderColor = Color.LightGray;
+ public static float TabBorderThickness = 2;
+
+ // Close tab button (X)
+
+ public static SolidBrush TabCloseButton_TextColor = new SolidBrush(Color.DarkSlateGray);
+ public static SolidBrush TabCloseButton_RollOverColor = new SolidBrush(Color.LightGray);
+
+ // New tab button (+)
+
+ public static SolidBrush TabNewButton_TextColor = new SolidBrush(Color.DarkSlateGray);
+ public static SolidBrush TabNewButton_RollOverColor = new SolidBrush(Color.LightGray);
+
+
+ }
+}
diff --git a/src/Controls/BorderedTextBox.cs b/src/Controls/BorderedTextBox.cs
new file mode 100644
index 0000000..00d95f1
--- /dev/null
+++ b/src/Controls/BorderedTextBox.cs
@@ -0,0 +1,141 @@
+using SharpBrowser.Config;
+using SharpBrowser.Utils;
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Drawing;
+using System.Drawing.Drawing2D;
+using System.Linq;
+using System.Reflection.Metadata;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows.Forms;
+
+namespace SharpBrowser.Controls {
+ public static class BorderedTextBoxUtils {
+
+ ///
+ /// Wraps an exisiting textbox with a panel which has roundd borders and a custom backcolor.
+ /// Returns the panel which wraps the textbox.
+ ///
+ public static BorderedTextBox ToBordered(this TextBox tbx) {
+
+ //backup previous TBX status
+ var tbxOriginalParent = tbx.Parent;
+ var loc = tbx.Location;
+ var size = tbx.Size;
+ var anchor = tbx.Anchor;
+ var dock = tbx.Dock;
+
+
+ //restore them to Panel
+ var panel = new BorderedTextBox(tbx);
+ panel.Location = loc;
+ panel.Size = size;
+ //bordered_tbx.Height= size.Height+5;
+ panel.Anchor = anchor;
+ panel.Dock = dock;
+ tbxOriginalParent.Controls.Add(panel);
+
+
+ panel.BackColor = Color.Transparent;
+
+ //remove tbx min size. it causes tbx getting clipped.
+ if (tbx.MinimumSize.Height != 0 && tbx.MinimumSize.Height >= panel.MinimumSize.Height) {
+ tbx.MinimumSize = new Size();
+ }
+
+
+ return panel;
+ }
+ }
+
+ public class BorderedTextBox : Panel {
+ private TextBox textBox;
+ private bool focusedAlways = false;
+ private Color normalBorderColor = Color.LightGray;
+ private Color focusedBorderColor = Color.FromArgb(153, 187, 239); //edge light blue
+ public int borderThickness = 2;
+
+ public TextBox TextBox {
+ get { return textBox; }
+ //set { textBox = value; }
+ }
+ public bool FocusedAlways {
+ get { return focusedAlways; }
+ set { focusedAlways = value; }
+ }
+
+ public BorderedTextBox(TextBox tbx = null) {
+ this.DoubleBuffered = true;
+ this.Padding = new Padding(1 + borderThickness * 2);
+ this.Height += borderThickness * 2;
+
+ if (tbx == null)
+ textBox = new TextBox();
+ else
+ textBox = tbx;
+
+ this.TextBox.AutoSize = false;
+ this.TextBox.BorderStyle = BorderStyle.None;
+ this.TextBox.Dock = DockStyle.Fill;
+ this.TextBox.Enter += TextBox_Refresh;
+ this.TextBox.Leave += TextBox_Refresh;
+ this.TextBox.Resize += TextBox_Refresh;
+ this.Controls.Add(this.TextBox);
+
+ }
+
+
+
+ private void TextBox_Refresh(object sender, EventArgs e) => this.Invalidate();
+
+ protected override void OnPaint(PaintEventArgs e) {
+ this.Padding = new Padding(
+ left: 15 + borderThickness,
+ right: 15 + borderThickness,
+ top: 1 + borderThickness + 5,
+ bottom: borderThickness + 5
+ );
+
+ this.AutoSize = false;
+ var txtHeight = MeasureHeight(textBox);
+ this.Height = txtHeight
+ + Padding.Top + Padding.Bottom;
+
+
+ var color = this.TextBox.Focused || focusedAlways ? focusedBorderColor : normalBorderColor;
+ using (Pen borderPen = new Pen(color, borderThickness)) {
+ var brushbg = new SolidBrush(textBox.BackColor);
+
+ var w = this.ClientSize.Width - borderThickness * 2;
+ var h = this.ClientSize.Height - borderThickness * 2;
+ var radius = h / 2;
+
+ e.Graphics.FillRoundRectangle(brushbg,
+ new Rectangle(0 + borderThickness, 0 + borderThickness,w,h),radius);
+
+ e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
+
+ e.Graphics.DrawRoundRectangle(borderPen,
+ new Rectangle(0 + borderThickness, 0 + borderThickness,w,h),radius);
+ }
+ base.OnPaint(e);
+ }
+
+
+ static int MeasureHeight(TextBox textbox) {
+ Size size = TextRenderer.MeasureText("AĞÜüğGgpPa", textbox.Font, Size.Empty, TextFormatFlags.TextBoxControl);
+ //textbox.MinimumSize = new Size(0, s.Height + 1 + 3);
+ return size.Height;
+
+ }
+
+
+ }
+
+
+
+}
\ No newline at end of file
diff --git a/src/Controls/BrowserTabStrip/BaseStyledPanel.cs b/src/Controls/BrowserTabStrip/BaseStyledPanel.cs
new file mode 100644
index 0000000..702a167
--- /dev/null
+++ b/src/Controls/BrowserTabStrip/BaseStyledPanel.cs
@@ -0,0 +1,59 @@
+using System;
+using System.ComponentModel;
+using System.Windows.Forms;
+using System.Windows.Forms.VisualStyles;
+
+namespace SharpBrowser.Controls.BrowserTabStrip {
+ [ToolboxItem(false)]
+ public class BaseStyledPanel : ContainerControl {
+ private static ToolStripProfessionalRenderer renderer;
+
+ [Browsable(false)]
+ public ToolStripProfessionalRenderer ToolStripRenderer => renderer;
+
+ [Browsable(false)]
+ [DefaultValue(true)]
+ public bool UseThemes {
+ get {
+ if (VisualStyleRenderer.IsSupported && VisualStyleInformation.IsSupportedByOS) {
+ return Application.RenderWithVisualStyles;
+ }
+ return false;
+ }
+ }
+
+ public event EventHandler ThemeChanged;
+
+ static BaseStyledPanel() {
+ renderer = new ToolStripProfessionalRenderer();
+ }
+
+ public BaseStyledPanel() {
+ SetStyle(ControlStyles.AllPaintingInWmPaint, value: true);
+ SetStyle(ControlStyles.OptimizedDoubleBuffer, value: true);
+ SetStyle(ControlStyles.ResizeRedraw, value: true);
+ SetStyle(ControlStyles.UserPaint, value: true);
+ }
+
+ protected override void OnSystemColorsChanged(EventArgs e) {
+ base.OnSystemColorsChanged(e);
+ UpdateRenderer();
+ Invalidate();
+ }
+
+ protected virtual void OnThemeChanged(EventArgs e) {
+ if (this.ThemeChanged != null) {
+ this.ThemeChanged(this, e);
+ }
+ }
+
+ private void UpdateRenderer() {
+ if (!UseThemes) {
+ renderer.ColorTable.UseSystemColors = true;
+ }
+ else {
+ renderer.ColorTable.UseSystemColors = false;
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Properties/Resources.resx b/src/Controls/BrowserTabStrip/BaseStyledPanel.resx
similarity index 100%
rename from src/Properties/Resources.resx
rename to src/Controls/BrowserTabStrip/BaseStyledPanel.resx
diff --git a/src/Controls/BrowserTabStrip/BrowserTabPage.cs b/src/Controls/BrowserTabStrip/BrowserTabPage.cs
new file mode 100644
index 0000000..bfe80f1
--- /dev/null
+++ b/src/Controls/BrowserTabStrip/BrowserTabPage.cs
@@ -0,0 +1,209 @@
+using System;
+using System.ComponentModel;
+using System.Drawing;
+using System.Windows.Forms;
+
+namespace SharpBrowser.Controls.BrowserTabStrip {
+
+ ///
+ /// This is a panel that holds controls to be displayed in this tab, like the web browser.
+ ///
+ [ToolboxItem(false)]
+ [DefaultProperty("Title")]
+ [DefaultEvent("Changed")]
+ public class BrowserTabPage : Panel {
+ private RectangleF stripRect = Rectangle.Empty;
+
+ private Bitmap image;
+
+ private bool canClose = true;
+
+ private bool selected;
+
+ private bool visible = true;
+
+ private bool isDrawn;
+
+ private string title = string.Empty;
+
+ [Browsable(false)]
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public new Size Size {
+ get {
+ return base.Size;
+ }
+ set {
+ base.Size = value;
+ }
+ }
+
+ [DefaultValue(true)]
+ public new bool Visible {
+ get {
+ return visible;
+ }
+ set {
+ if (visible != value) {
+ visible = value;
+ OnChanged();
+ }
+ }
+ }
+
+ internal RectangleF StripRect {
+ get {
+ return stripRect;
+ }
+ set {
+ stripRect = value;
+ }
+ }
+
+ [DefaultValue(false)]
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ [Browsable(false)]
+ public bool IsDrawn {
+ get {
+ return isDrawn;
+ }
+ set {
+ if (isDrawn != value) {
+ isDrawn = value;
+ }
+ }
+ }
+
+ [DefaultValue(null)]
+ public Bitmap Image {
+ get {
+ return image;
+ }
+ set {
+ if (image != value) {
+ image = value;
+ OnChanged();
+ }
+ }
+ }
+
+ [DefaultValue(true)]
+ public bool CanClose {
+ get {
+ return canClose;
+ }
+ set {
+ canClose = value;
+ }
+ }
+
+ [DefaultValue("Name")]
+ public string Title {
+ get {
+ return title;
+ }
+ set {
+ if (!(title == value)) {
+ title = value;
+ OnChanged();
+ }
+ }
+ }
+
+ [DefaultValue(false)]
+ [Browsable(false)]
+ public bool Selected {
+ get {
+ return selected;
+ }
+ set {
+ if (selected != value) {
+ selected = value;
+ }
+ }
+ }
+
+ [Browsable(false)]
+ public string Caption => Title;
+
+ public event EventHandler Changed;
+
+ public BrowserTabPage()
+ : this(string.Empty, null) {
+ }
+
+ public BrowserTabPage(Control displayControl)
+ : this(string.Empty, displayControl) {
+ }
+
+ public BrowserTabPage(string caption, Control displayControl) {
+ SetStyle(ControlStyles.OptimizedDoubleBuffer, value: true);
+ SetStyle(ControlStyles.ResizeRedraw, value: true);
+ SetStyle(ControlStyles.UserPaint, value: true);
+ SetStyle(ControlStyles.AllPaintingInWmPaint, value: true);
+ SetStyle(ControlStyles.ContainerControl, value: true);
+ selected = false;
+ Visible = true;
+ UpdateText(caption, displayControl);
+ if (displayControl != null) {
+ base.Controls.Add(displayControl);
+ }
+ }
+
+ protected override void Dispose(bool disposing) {
+ base.Dispose(disposing);
+
+ // don't dispose favicons as they are shared across multiple tabs
+ /*if (disposing && image != null) {
+ image.Dispose();
+ }*/
+ }
+
+ public bool ShouldSerializeIsDrawn() {
+ return false;
+ }
+
+ public bool ShouldSerializeDock() {
+ return false;
+ }
+
+ public bool ShouldSerializeControls() {
+ if (base.Controls != null) {
+ return base.Controls.Count > 0;
+ }
+ return false;
+ }
+
+ public bool ShouldSerializeVisible() {
+ return true;
+ }
+
+ private void UpdateText(string caption, Control displayControl) {
+ if (caption.Length <= 0 && displayControl != null) {
+ Title = displayControl.Text;
+ }
+ else if (caption != null) {
+ Title = caption;
+ }
+ else {
+ Title = string.Empty;
+ }
+ }
+
+ public void Assign(BrowserTabPage item) {
+ Visible = item.Visible;
+ Text = item.Text;
+ CanClose = item.CanClose;
+ base.Tag = item.Tag;
+ }
+
+ protected internal virtual void OnChanged() {
+ if (this.Changed != null) {
+ this.Changed(this, EventArgs.Empty);
+ }
+ }
+
+ public override string ToString() {
+ return Caption;
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Controls/BrowserTabStrip/BrowserTabPage.resx b/src/Controls/BrowserTabStrip/BrowserTabPage.resx
new file mode 100644
index 0000000..1af7de1
--- /dev/null
+++ b/src/Controls/BrowserTabStrip/BrowserTabPage.resx
@@ -0,0 +1,120 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
\ No newline at end of file
diff --git a/src/Controls/BrowserTabStrip/BrowserTabStrip.cs b/src/Controls/BrowserTabStrip/BrowserTabStrip.cs
new file mode 100644
index 0000000..c5c6d5d
--- /dev/null
+++ b/src/Controls/BrowserTabStrip/BrowserTabStrip.cs
@@ -0,0 +1,623 @@
+using SharpBrowser.Config;
+using SharpBrowser.Controls.BrowserTabStrip.Buttons;
+using SharpBrowser.Utils;
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Drawing;
+using System.Drawing.Drawing2D;
+using System.Windows.Forms;
+
+namespace SharpBrowser.Controls.BrowserTabStrip {
+
+ ///
+ /// This is the tab strip that displays tab buttons that are clickable, as well as tab pages.
+ ///
+ [DefaultEvent("TabStripItemSelectionChanged")]
+ [DefaultProperty("Items")]
+ [ToolboxItem(true)]
+ internal class BrowserTabStrip : BaseStyledPanel, ISupportInitialize, IDisposable {
+
+ public int TabButton_Height => BrowserTabStyle.TabHeight;
+
+ private BrowserTabPage selectedItem;
+ private ContextMenuStrip menu;
+ private CloseTabButton closeButton;
+ private NewTabButton newTabButton;
+ private BrowserTabStripItemCollection items;
+
+ private StringFormat DrawStringFormat;
+
+ private bool isIniting;
+ public int MaxTabSize = 200;
+ public int AddButtonWidth = 40;
+
+ private Point LastMousePos;
+
+ [RefreshProperties(RefreshProperties.All)]
+ [DefaultValue(null)]
+ public BrowserTabPage SelectedTab {
+ get {
+ return selectedItem;
+ }
+ set {
+ if (selectedItem == value) {
+ return;
+ }
+ if (value == null && Items.Count > 0) {
+ /*BrowserTabItem fATabStripItem = Items[0];
+ if (fATabStripItem.Visible) {
+ selectedItem = fATabStripItem;
+ selectedItem.Selected = true;
+ selectedItem.Dock = DockStyle.Fill;
+ }*/
+ selectedItem = null;
+ return;
+ }
+ else {
+ selectedItem = value;
+ }
+
+ foreach (BrowserTabPage item in Items) {
+ if (item == selectedItem) {
+ SelectItem(item);
+ //item.Dock = DockStyle.Fill;
+ item.Show();
+ }
+ else {
+ UnSelectItem(item);
+ item.Hide();
+ }
+ }
+ Invalidate();
+ Refresh();
+
+ /*SelectItem(selectedItem);
+ Invalidate();
+ if (!selectedItem.IsDrawn) {
+ Items.MoveTo(0, selectedItem);
+ Invalidate();
+ }*/
+ OnTabStripItemChanged(new TabStripItemChangedEventArgs(selectedItem, BrowserTabStripItemChangeTypes.SelectionChanged));
+ }
+ }
+
+ [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
+ public BrowserTabStripItemCollection Items => items;
+
+ [DefaultValue(typeof(Size), "350,200")]
+ public new Size Size {
+ get {
+ return base.Size;
+ }
+ set {
+ if (!(base.Size == value)) {
+ base.Size = value;
+ UpdateLayout();
+ }
+ }
+ }
+
+ [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
+ public new ControlCollection Controls => base.Controls;
+
+ public event TabStripItemClosingHandler TabStripItemClosing;
+ public event TabStripItemChangedHandler TabStripItemSelectionChanged;
+ public event HandledEventHandler MenuItemsLoading;
+ public event EventHandler MenuItemsLoaded;
+ public event EventHandler TabStripItemClosed;
+ public event EventHandler TabStripNewTab;
+
+ public BrowserTabStrip() {
+ BeginInit();
+ SetStyle(ControlStyles.ContainerControl, value: true);
+ SetStyle(ControlStyles.UserPaint, value: true);
+ SetStyle(ControlStyles.ResizeRedraw, value: true);
+ SetStyle(ControlStyles.AllPaintingInWmPaint, value: true);
+ SetStyle(ControlStyles.OptimizedDoubleBuffer, value: true);
+ SetStyle(ControlStyles.Selectable, value: true);
+ items = new BrowserTabStripItemCollection();
+ items.CollectionChanged += OnCollectionChanged;
+ base.Size = new Size(350, 200);
+ menu = new ContextMenuStrip();
+ menu.Renderer = base.ToolStripRenderer;
+ menu.ItemClicked += OnMenuItemClicked;
+ menu.VisibleChanged += OnMenuVisibleChanged;
+ closeButton = new CloseTabButton(base.ToolStripRenderer);
+ newTabButton = new NewTabButton(base.ToolStripRenderer);
+ DrawStringFormat = new StringFormat();
+ EndInit();
+ UpdateLayout();
+ }
+
+ public HitTestResult HitTest(Point pt) {
+ if (newTabButton.IsVisible && newTabButton.Rect.Contains(pt)) {
+ return HitTestResult.NewButton;
+ }
+ if (closeButton.IsVisible && closeButton.Rect.Contains(pt)) {
+ return HitTestResult.CloseButton;
+ }
+ if (GetTabItemByPoint(pt) != null) {
+ return HitTestResult.TabItem;
+ }
+ return HitTestResult.None;
+ }
+
+ public void AddTab(BrowserTabPage tabItem) => AddTab(tabItem, autoSelect: false);
+
+ public void AddTab(BrowserTabPage tabItem, bool autoSelect) {
+
+ // add this tab to my collection
+ tabItem.Dock = DockStyle.Fill;
+ Items.Add(tabItem);
+
+ // select the new tab
+ if ((autoSelect && tabItem.Visible) || (tabItem.Visible && Items.DrawnCount < 1)) {
+ SelectedTab = tabItem;
+ SelectItem(tabItem);
+ }
+ }
+
+ public void RemoveTab(BrowserTabPage tabItem) {
+
+ // if tab is found in my collection
+ int num = Items.IndexOf(tabItem);
+ if (num >= 0) {
+
+ // remove the tab
+ UnSelectItem(tabItem);
+ Items.Remove(tabItem);
+
+ // select last item
+ if (Items.Count > 0) {
+ if (Items[num] != null) {
+ SelectedTab = Items[num];
+ }
+ else {
+ SelectedTab = Items[items.Count - 1];
+ }
+ }
+ }
+ }
+
+ public BrowserTabPage GetTabItemByPoint(Point pt) {
+ BrowserTabPage result = null;
+ bool flag = false;
+ for (int i = 0; i < Items.Count; i++) {
+ BrowserTabPage fATabStripItem = Items[i];
+ if (fATabStripItem.StripRect.Contains(pt) && fATabStripItem.Visible && fATabStripItem.IsDrawn) {
+ result = fATabStripItem;
+ flag = true;
+ }
+ if (flag) {
+ break;
+ }
+ }
+ return result;
+ }
+
+ public virtual void ShowMenu() { }
+
+ internal void UnDrawAll() {
+ for (int i = 0; i < Items.Count; i++) {
+ Items[i].IsDrawn = false;
+ }
+ }
+
+ internal void SelectItem(BrowserTabPage tabItem) {
+ //tabItem.Dock = DockStyle.Fill;
+ tabItem.Visible = true;
+ tabItem.Selected = true;
+ }
+
+ internal void UnSelectItem(BrowserTabPage tabItem) => tabItem.Selected = false;
+
+ protected internal virtual void OnTabStripItemClosing(TabStripItemClosingEventArgs e) => this.TabStripItemClosing?.Invoke(e);
+
+ protected internal virtual void OnTabStripItemClosed(EventArgs e) {
+ this.TabStripItemClosed?.Invoke(this, e);
+ }
+ protected internal virtual void OnTabStripNewTab(EventArgs e) {
+ this.TabStripNewTab?.Invoke(this, e);
+ }
+
+
+ protected virtual void OnMenuItemsLoading(HandledEventArgs e) => this.MenuItemsLoading?.Invoke(this, e);
+
+ protected virtual void OnMenuItemsLoaded(EventArgs e) {
+ if (this.MenuItemsLoaded != null) {
+ this.MenuItemsLoaded(this, e);
+ }
+ }
+
+ protected virtual void OnTabStripItemChanged(TabStripItemChangedEventArgs e) {
+ this.TabStripItemSelectionChanged?.Invoke(e);
+ }
+
+ protected virtual void OnMenuItemsLoad(EventArgs e) {
+ menu.RightToLeft = RightToLeft;
+ menu.Items.Clear();
+ for (int i = 0; i < Items.Count; i++) {
+ BrowserTabPage fATabStripItem = Items[i];
+ if (fATabStripItem.Visible) {
+ ToolStripMenuItem toolStripMenuItem = new ToolStripMenuItem(fATabStripItem.Title);
+ toolStripMenuItem.Tag = fATabStripItem;
+ toolStripMenuItem.Image = fATabStripItem.Image;
+ menu.Items.Add(toolStripMenuItem);
+ }
+ }
+ OnMenuItemsLoaded(EventArgs.Empty);
+ }
+
+ protected override void OnRightToLeftChanged(EventArgs e) {
+ base.OnRightToLeftChanged(e);
+ UpdateLayout();
+ Invalidate();
+ }
+
+ protected override void OnMouseDown(MouseEventArgs e) {
+ base.OnMouseDown(e);
+ HitTestResult hitTestResult = HitTest(e.Location);
+
+ if (hitTestResult == HitTestResult.TabItem) {
+
+ // select the tab if clicked
+ BrowserTabPage tabItemByPoint = GetTabItemByPoint(e.Location);
+ if (tabItemByPoint != null) {
+ SelectedTab = tabItemByPoint;
+ Invalidate();
+ }
+
+ // close if middle clicked on a tab
+ if (e.Button == MouseButtons.Middle) {
+ CloseActiveTab();
+ }
+
+ }
+ else if (hitTestResult == HitTestResult.CloseButton) {
+ if (e.Button == MouseButtons.Left) {
+ CloseActiveTab();
+ }
+ }
+ else if (hitTestResult == HitTestResult.NewButton) {
+ if (e.Button == MouseButtons.Left) {
+ OnTabStripNewTab(EventArgs.Empty);
+ }
+ }
+ }
+
+ private void CloseActiveTab() {
+ if (SelectedTab != null) {
+ TabStripItemClosingEventArgs tabStripItemClosingEventArgs = new TabStripItemClosingEventArgs(SelectedTab);
+ OnTabStripItemClosing(tabStripItemClosingEventArgs);
+ if (!tabStripItemClosingEventArgs.Cancel && SelectedTab.CanClose) {
+ RemoveTab(SelectedTab);
+ OnTabStripItemClosed(EventArgs.Empty);
+ }
+ }
+ Invalidate();
+ }
+
+ protected override void OnMouseMove(MouseEventArgs e) {
+ base.OnMouseMove(e);
+
+ LastMousePos = e.Location;
+
+ // manually process events for buttons
+ closeButton.ProcessRolloverEvents(this, e);
+ newTabButton.ProcessRolloverEvents(this, e);
+
+ this.Invalidate();
+ }
+
+
+ protected override void OnMouseLeave(EventArgs e) {
+ base.OnMouseLeave(e);
+
+ LastMousePos = Point.Empty;
+
+ // manually process events for buttons
+ closeButton.ProcessRolloutEvents(this);
+ newTabButton.ProcessRolloutEvents(this);
+
+ this.Invalidate();
+ }
+
+ protected override void OnSizeChanged(EventArgs e) {
+ base.OnSizeChanged(e);
+ if (!isIniting) {
+ UpdateLayout();
+ }
+ }
+
+ private void OnMenuItemClicked(object sender, ToolStripItemClickedEventArgs e) {
+ BrowserTabPage fATabStripItem2 = (SelectedTab = (BrowserTabPage)e.ClickedItem.Tag);
+ }
+
+ private void OnMenuVisibleChanged(object sender, EventArgs e) {
+ if (!menu.Visible) {
+ }
+ }
+
+ ///
+ /// Main rendering of the entire tab strip.
+ ///
+ protected override void OnPaint(PaintEventArgs e) {
+ //SetDefaultSelected();
+ Rectangle clientRectangle = base.ClientRectangle;
+ clientRectangle.Width--;
+ clientRectangle.Height--;
+ TabStartX = BrowserTabStyle.TabLeftPadding;
+ e.Graphics.DrawRectangle(SystemPens.ControlDark, clientRectangle);
+ e.Graphics.FillRectangle(Brushes.White, clientRectangle);
+ e.Graphics.FillRectangle(BrowserTabStyle.BackColor, new Rectangle(clientRectangle.X, clientRectangle.Y, clientRectangle.Width, BrowserTabStyle.TabHeight));
+ e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
+
+
+ //--------------------------------------------------------
+ // DRAW ALL TABS
+ for (int i = 0; i < Items.Count; i++) {
+ BrowserTabPage fATabStripItem = Items[i];
+ if (fATabStripItem.Visible || base.DesignMode) {
+ OnCalcTabPage(e.Graphics, fATabStripItem);
+ fATabStripItem.IsDrawn = false;
+ DrawSingleTabButton(e.Graphics, fATabStripItem);
+ }
+ }
+
+ //--------------------------------------------------------
+ // DRAW BOTTOM LINE on the left/right side of the selected tab
+
+ if (SelectedTab != null && SelectedTab.IsDrawn) {
+ var lineColorPen = new Pen(BrowserTabStyle.TabBorderColor, BrowserTabStyle.TabBorderThickness);
+
+ Point point = new Point((int)SelectedTab.StripRect.Left - TabRadius, BrowserTabStyle.TabHeight);
+ e.Graphics.DrawLine(lineColorPen, new Point(0, BrowserTabStyle.TabHeight), point);
+ point.X += (int)SelectedTab.StripRect.Width + TabRadius + 2;
+ e.Graphics.DrawLine(lineColorPen, point, new Point(base.ClientRectangle.Width, BrowserTabStyle.TabHeight));
+ }
+
+ //--------------------------------------------------------
+ // DRAW CLOSE BUTTON FOR SELECTED TAB
+ if (SelectedTab != null && SelectedTab.CanClose) {
+ closeButton.IsVisible = true;
+ closeButton.CalcBounds(selectedItem, true);
+ closeButton.Draw(e.Graphics);
+ }
+ else {
+ closeButton.IsVisible = false;
+ }
+
+ //--------------------------------------------------------
+ // DRAW NEW BUTTON
+ newTabButton.IsVisible = true;
+ newTabButton.CalcBounds(Items[items.Count - 1], false);
+ newTabButton.Draw(e.Graphics);
+ //--------------------------------------------------------
+
+ }
+
+ ///
+ /// ready for future use, (_ [] X) , if we put Tabs and Close/Minimize buttons on TitleBar
+ ///
+ int atRight_ReservedWidth = 250;
+ private int TabStartX = BrowserTabStyle.TabLeftPadding;
+ private void OnCalcTabPage(Graphics g, BrowserTabPage currentItem) {
+ //_ = Font;
+ int calcWidth = 0;
+ calcWidth = (base.Width - atRight_ReservedWidth - (AddButtonWidth + 20)) / Math.Max(1, (items.Count - 1));
+ if (calcWidth > MaxTabSize) {
+ calcWidth = MaxTabSize;
+ }
+ RectangleF rectangleF2 = (currentItem.StripRect = new RectangleF(TabStartX, 3f, calcWidth, BrowserTabStyle.TabHeight));
+ TabStartX += calcWidth;
+ }
+
+
+
+ bool styleNotPill = true;
+ int TabRadius = 8;
+
+
+ ///
+ /// Draws a single tab header button.
+ ///
+ private void DrawSingleTabButton(Graphics g, BrowserTabPage tab) {
+ Items.IndexOf(tab);
+ Font font = Font;
+
+ bool isActiveTab = tab == SelectedTab;
+ bool is_atRightof_ActiveTab = Items.IndexOf(tab) == Items.IndexOf(selectedItem) + 1;
+
+ RectangleF stripRect = tab.StripRect;
+ var sr = stripRect;
+
+ //--------------------------------------------------------
+ // Calc Rect for the Tab
+ //--------------------------------------------------------
+ var tabDrawnRect = new RectangleF(sr.Left, 1, sr.Width - 2, sr.Height - 2);
+ //tabDrawnRect.Height += 2; // hides bottom Line of Rect.
+ tabDrawnRect.Y += 8;
+ tabDrawnRect.Height -= 8;
+ if (styleNotPill)
+ tabDrawnRect.Height += 2;
+ //--------------------------------------------------------
+
+ ////--Draw Rectange Tabs
+ //g.FillRectangle(brush, tabDrawnRect);
+ //g.DrawRectangle(SystemPens.ControlDark, tabDrawnRect);
+
+ ////--Draw Pill Style Tabs
+ //g.FillRoundRectangle(brush, tabDrawnRect,TabRadius);
+ //g.DrawRoundRectangle(SystemPens.ControlDark, tabDrawnRect, TabRadius);
+
+ //--------------------------------------------------------
+ // Style for the tab button
+ //--------------------------------------------------------
+ var tabColor = BrowserTabStyle.TabBackColor_Normal;
+ var borderColor = BrowserTabStyle.TabBackColor_Normal;
+ if (tab == SelectedTab) {
+ tabColor = BrowserTabStyle.TabBackColor_Selected;
+ borderColor = BrowserTabStyle.TabBorderColor;
+ }
+ else if (tabDrawnRect.Contains(LastMousePos)) {
+ tabColor = BrowserTabStyle.TabBackColor_Rollover;
+ }
+ var brush = new SolidBrush(tabColor);
+ var pen = new Pen(borderColor, BrowserTabStyle.TabBorderThickness);
+
+ //--------------------------------------------------------
+ // Rounded Chrome Tabs
+ //--------------------------------------------------------
+ var tabpathNew =
+ isActiveTab ?
+ tabDrawnRect.CreateTabPath_Roundtop_RoundBottomOut(TabRadius) :
+ tabDrawnRect.CreateTabPath_roundAll(TabRadius);
+
+ g.FillPath(brush, tabpathNew);
+ g.DrawPath(pen, tabpathNew);
+ // draw tab seperator line: | TAB1 | TAB2
+ if (!isActiveTab && !is_atRightof_ActiveTab) {
+ int margin = 14;
+ sr.Y += 2; //move rect down
+ g.DrawLine(SystemPens.ControlDark, sr.X, sr.Y + margin, sr.X, sr.Y + sr.Height - margin);
+ }
+
+ //g.DrawPath(SystemPens.ControlDark, graphicsPath);
+ if (tab == SelectedTab) {
+ //g.DrawLine(new Pen(brush), sr_left + 19f, sr_height + 2f, sr_left + sr_width - 1f, sr_height + 2f);
+ }
+ //--------------------------------------------------------
+
+ var ForeColorSel = ForeColor;
+
+
+ //--------------------------------------------------------
+ // Tab Text
+ //--------------------------------------------------------
+
+ // margin for Tab Text, Vertically Center
+ var textRect = tabDrawnRect;
+ textRect.X += 10;
+ textRect.Width -= 10;
+
+ // leave gap for icon if any
+ if (tab.Image != null) {
+ var extraSize = BrowserTabStyle.Tab_IconSize + 5;
+ textRect.X += extraSize;
+ textRect.Width -= extraSize;
+ }
+
+ // draw tab text title
+ if (tab == SelectedTab)
+ {
+ textRect.Width -= 25;
+ }
+ // FIX: fix janky text rendering and bad kerning by using TextRenderer instead of DrawString
+ g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.ClearTypeGridFit;
+ TextRenderer.DrawText(g,tab.Title,font,Rectangle.Round(textRect),ForeColorSel,
+ TextFormatFlags.Left | TextFormatFlags.VerticalCenter | TextFormatFlags.EndEllipsis
+ );
+ //--------------------------------------------------------
+
+
+ //--------------------------------------------------------
+ // Tab Icon
+ //--------------------------------------------------------
+ if (tab.Image != null) {
+
+ // center align the icon in the given space, but right align it to the text
+ var size = (int)BrowserTabStyle.Tab_IconSize;
+ var iconX = textRect.X - (5 + size);
+ var iconY = textRect.Y + ((textRect.Height - size) / 2);
+
+ // draw tab icon
+ g.InterpolationMode = InterpolationMode.NearestNeighbor;
+ g.DrawImage(tab.Image, (int)iconX, (int)iconY, size, size);
+ }
+
+
+ tab.IsDrawn = true;
+ }
+
+
+ private void UpdateLayout() {
+ //sf.Trimming = StringTrimming.Character;
+ DrawStringFormat.Trimming = StringTrimming.EllipsisCharacter;
+ DrawStringFormat.FormatFlags = StringFormatFlags.NoWrap;
+ //sf.FormatFlags |= StringFormatFlags.DirectionRightToLeft; //this line causes multiline.//is this arabic??
+ DrawStringFormat.LineAlignment = StringAlignment.Center;
+
+ DrawStringFormat.Alignment = StringAlignment.Near;
+
+ base.DockPadding.Top = BrowserTabStyle.TabHeight + 1;
+ base.DockPadding.Bottom = 1;
+ base.DockPadding.Right = 1;
+ base.DockPadding.Left = 1;
+ }
+
+ private void OnCollectionChanged(object sender, CollectionChangeEventArgs e) {
+ BrowserTabPage fATabStripItem = (BrowserTabPage)e.Element;
+ if (e.Action == CollectionChangeAction.Add) {
+ Controls.Add(fATabStripItem);
+ OnTabStripItemChanged(new TabStripItemChangedEventArgs(fATabStripItem, BrowserTabStripItemChangeTypes.Added));
+ }
+ else if (e.Action == CollectionChangeAction.Remove) {
+ Controls.Remove(fATabStripItem);
+ OnTabStripItemChanged(new TabStripItemChangedEventArgs(fATabStripItem, BrowserTabStripItemChangeTypes.Removed));
+ }
+ else {
+ OnTabStripItemChanged(new TabStripItemChangedEventArgs(fATabStripItem, BrowserTabStripItemChangeTypes.Changed));
+ }
+ UpdateLayout();
+ Invalidate();
+ }
+
+ public bool ShouldSerializeSelectedItem() => true;
+ public bool ShouldSerializeItems() => items.Count > 0;
+ public void BeginInit() => isIniting = true;
+ public void EndInit() => isIniting = false;
+
+ protected override void Dispose(bool disposing) {
+ if (disposing) {
+ items.CollectionChanged -= OnCollectionChanged;
+ menu.ItemClicked -= OnMenuItemClicked;
+ menu.VisibleChanged -= OnMenuVisibleChanged;
+ foreach (BrowserTabPage item in items) {
+ if (item != null && !item.IsDisposed) {
+ item.Dispose();
+ }
+ }
+ if (menu != null && !menu.IsDisposed) {
+ menu.Dispose();
+ }
+ if (DrawStringFormat != null) {
+ DrawStringFormat.Dispose();
+ }
+ }
+ base.Dispose(disposing);
+ }
+
+ public List Tabs {
+ get {
+ var tabs = new List();
+ foreach (BrowserTabPage item in items) {
+ tabs.Add(item);
+ }
+ return tabs;
+ }
+ }
+
+ public int SelectedIndex {
+ get {
+ return Items.IndexOf(SelectedTab);
+ }
+ set {
+ if (Items[value] != null) {
+ SelectedTab = Items[value];
+ }
+ }
+ }
+
+ }
+}
\ No newline at end of file
diff --git a/src/Controls/BrowserTabStrip/BrowserTabStrip.resx b/src/Controls/BrowserTabStrip/BrowserTabStrip.resx
new file mode 100644
index 0000000..1af7de1
--- /dev/null
+++ b/src/Controls/BrowserTabStrip/BrowserTabStrip.resx
@@ -0,0 +1,120 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
\ No newline at end of file
diff --git a/src/Controls/BrowserTabStrip/Buttons/CloseTabButton.cs b/src/Controls/BrowserTabStrip/Buttons/CloseTabButton.cs
new file mode 100644
index 0000000..59c0c90
--- /dev/null
+++ b/src/Controls/BrowserTabStrip/Buttons/CloseTabButton.cs
@@ -0,0 +1,24 @@
+using SharpBrowser.Config;
+using SharpBrowser.Utils;
+using System.Drawing;
+using System.Windows.Forms;
+
+namespace SharpBrowser.Controls.BrowserTabStrip.Buttons {
+ internal class CloseTabButton(ToolStripProfessionalRenderer renderer) : TabButtonBase(renderer) {
+
+ public override void Draw(Graphics g) {
+ if (IsVisible) {
+ //g.FillRectangle(Brushes.White, Rect);
+ if (IsMouseOver) {
+ g.FillRoundRectangle(BrowserTabStyle.TabCloseButton_RollOverColor, Rect, 10);
+ }
+ int padding = 6;
+ Pen pen = new Pen(BrowserTabStyle.TabCloseButton_TextColor, 1.6f);
+ g.DrawLine(pen, Rect.Left + padding, Rect.Top + padding, Rect.Right - padding, Rect.Bottom - padding);
+ g.DrawLine(pen, Rect.Right - padding, Rect.Top + padding, Rect.Left + padding, Rect.Bottom - padding);
+ pen.Dispose();
+ }
+ }
+
+ }
+}
\ No newline at end of file
diff --git a/src/Controls/BrowserTabStrip/Buttons/NewTabButton.cs b/src/Controls/BrowserTabStrip/Buttons/NewTabButton.cs
new file mode 100644
index 0000000..d37d7e8
--- /dev/null
+++ b/src/Controls/BrowserTabStrip/Buttons/NewTabButton.cs
@@ -0,0 +1,26 @@
+using SharpBrowser.Config;
+using SharpBrowser.Utils;
+using System.Drawing;
+using System.Windows.Forms;
+
+namespace SharpBrowser.Controls.BrowserTabStrip.Buttons {
+ internal class NewTabButton(ToolStripProfessionalRenderer renderer) : TabButtonBase(renderer) {
+
+ public override void Draw(Graphics g) {
+ if (IsVisible) {
+ //g.FillRectangle(Brushes.White, Rect);
+ if (IsMouseOver) {
+ g.FillRoundRectangle(BrowserTabStyle.TabNewButton_RollOverColor, Rect, 10);
+ }
+ int num = 4;
+ int centerX = Rect.X + Rect.Width / 2;
+ int centerY = Rect.Y + Rect.Height / 2;
+ Pen pen = new Pen(BrowserTabStyle.TabNewButton_TextColor, 1.6f);
+ g.DrawLine(pen, centerX, Rect.Top + num, centerX, Rect.Bottom - num);
+ g.DrawLine(pen, Rect.Right - num, centerY, Rect.Left + num, centerY);
+ pen.Dispose();
+ }
+ }
+
+ }
+}
\ No newline at end of file
diff --git a/src/Controls/BrowserTabStrip/Buttons/TabButtonBase.cs b/src/Controls/BrowserTabStrip/Buttons/TabButtonBase.cs
new file mode 100644
index 0000000..ec0be13
--- /dev/null
+++ b/src/Controls/BrowserTabStrip/Buttons/TabButtonBase.cs
@@ -0,0 +1,44 @@
+using SharpBrowser.Config;
+using System.Drawing;
+using System.Windows.Forms;
+
+namespace SharpBrowser.Controls.BrowserTabStrip.Buttons {
+ internal abstract class TabButtonBase {
+
+ public Rectangle Rect = Rectangle.Empty;
+ public Rectangle RedrawRect = Rectangle.Empty;
+ public bool IsMouseOver;
+ public bool IsVisible;
+ public ToolStripProfessionalRenderer Renderer;
+
+ internal TabButtonBase(ToolStripProfessionalRenderer renderer) {
+ Renderer = renderer;
+ }
+
+ public void CalcBounds(BrowserTabPage tab, bool displayInButton) {
+ var tabrect = tab.StripRect;
+ var x = displayInButton ? (int)tab.StripRect.Right - BrowserTabStyle.TabCloseButton_XOffset : (int)tab.StripRect.Right + 10;
+ var y = (int)tab.StripRect.Top + BrowserTabStyle.TabButton_Y;
+ Rect = new Rectangle(x, y, 20, 20);
+ RedrawRect = new Rectangle(Rect.X - 2, Rect.Y - 2, Rect.Width + 4, Rect.Height + 4);
+ }
+
+ public virtual void Draw(Graphics g) {
+ }
+
+ public void ProcessRolloverEvents(Control parent, MouseEventArgs e) {
+ if (IsVisible) {
+ if (Rect.Contains(e.Location)) {
+ IsMouseOver = true;
+ }
+ else if (IsMouseOver) {
+ IsMouseOver = false;
+ }
+ }
+ }
+ public void ProcessRolloutEvents(Control parent) {
+ IsMouseOver = false;
+ }
+
+ }
+}
diff --git a/src/Controls/BrowserTabStrip/Data/BrowserTabStripItemCollection.cs b/src/Controls/BrowserTabStrip/Data/BrowserTabStripItemCollection.cs
new file mode 100644
index 0000000..e1a1a5e
--- /dev/null
+++ b/src/Controls/BrowserTabStrip/Data/BrowserTabStripItemCollection.cs
@@ -0,0 +1,175 @@
+using System;
+using System.ComponentModel;
+
+namespace SharpBrowser.Controls.BrowserTabStrip {
+ public class BrowserTabStripItemCollection : CollectionWithEvents {
+ private int lockUpdate;
+
+ public BrowserTabPage this[int index] {
+ get {
+ if (index < 0 || base.List.Count - 1 < index) {
+ return null;
+ }
+ return (BrowserTabPage)base.List[index];
+ }
+ set {
+ base.List[index] = value;
+ }
+ }
+
+ [Browsable(false)]
+ public virtual int DrawnCount {
+ get {
+ int count = base.Count;
+ int num = 0;
+ if (count == 0) {
+ return 0;
+ }
+ for (int i = 0; i < count; i++) {
+ if (this[i].IsDrawn) {
+ num++;
+ }
+ }
+ return num;
+ }
+ }
+
+ [Browsable(false)]
+ public virtual int VisibleCount {
+ get {
+ int count = base.Count;
+ int num = 0;
+ if (count == 0) {
+ return 0;
+ }
+ for (int i = 0; i < count; i++) {
+ if (this[i].Visible) {
+ num++;
+ }
+ }
+ return num;
+ }
+ }
+
+ [Browsable(false)]
+ public event CollectionChangeEventHandler CollectionChanged;
+
+ public BrowserTabStripItemCollection() {
+ lockUpdate = 0;
+ }
+
+ protected virtual void OnCollectionChanged(CollectionChangeEventArgs e) {
+ if (this.CollectionChanged != null) {
+ this.CollectionChanged(this, e);
+ }
+ }
+
+ protected virtual void BeginUpdate() {
+ lockUpdate++;
+ }
+
+ protected virtual void EndUpdate() {
+ if (--lockUpdate == 0) {
+ OnCollectionChanged(new CollectionChangeEventArgs(CollectionChangeAction.Refresh, null));
+ }
+ }
+
+ public virtual void AddRange(BrowserTabPage[] items) {
+ BeginUpdate();
+ try {
+ foreach (BrowserTabPage value in items) {
+ base.List.Add(value);
+ }
+ }
+ finally {
+ EndUpdate();
+ }
+ }
+
+ public virtual void Assign(BrowserTabStripItemCollection collection) {
+ BeginUpdate();
+ try {
+ Clear();
+ for (int i = 0; i < collection.Count; i++) {
+ BrowserTabPage item = collection[i];
+ BrowserTabPage fATabStripItem = new BrowserTabPage();
+ fATabStripItem.Assign(item);
+ Add(fATabStripItem);
+ }
+ }
+ finally {
+ EndUpdate();
+ }
+ }
+
+ public virtual int Add(BrowserTabPage item) {
+ int num = IndexOf(item);
+ if (num == -1) {
+ num = base.List.Add(item);
+ }
+ return num;
+ }
+
+ public virtual void Remove(BrowserTabPage item) {
+ if (base.List.Contains(item)) {
+ base.List.Remove(item);
+ }
+ }
+
+ public virtual BrowserTabPage MoveTo(int newIndex, BrowserTabPage item) {
+ int num = base.List.IndexOf(item);
+ if (num >= 0) {
+ RemoveAt(num);
+ Insert(0, item);
+ return item;
+ }
+ return null;
+ }
+
+ public virtual int IndexOf(BrowserTabPage item) {
+ return base.List.IndexOf(item);
+ }
+
+ public virtual bool Contains(BrowserTabPage item) {
+ return base.List.Contains(item);
+ }
+
+ public virtual void Insert(int index, BrowserTabPage item) {
+ if (!Contains(item)) {
+ base.List.Insert(index, item);
+ }
+ }
+
+ protected override void OnInsertComplete(int index, object item) {
+ BrowserTabPage fATabStripItem = item as BrowserTabPage;
+ fATabStripItem.Changed += OnItem_Changed;
+ OnCollectionChanged(new CollectionChangeEventArgs(CollectionChangeAction.Add, item));
+ }
+
+ protected override void OnRemove(int index, object item) {
+ base.OnRemove(index, item);
+ BrowserTabPage fATabStripItem = item as BrowserTabPage;
+ fATabStripItem.Changed -= OnItem_Changed;
+ OnCollectionChanged(new CollectionChangeEventArgs(CollectionChangeAction.Remove, item));
+ }
+
+ protected override void OnClear() {
+ if (base.Count == 0) {
+ return;
+ }
+ BeginUpdate();
+ try {
+ for (int num = base.Count - 1; num >= 0; num--) {
+ RemoveAt(num);
+ }
+ }
+ finally {
+ EndUpdate();
+ }
+ }
+
+ protected virtual void OnItem_Changed(object sender, EventArgs e) {
+ OnCollectionChanged(new CollectionChangeEventArgs(CollectionChangeAction.Refresh, sender));
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Controls/BrowserTabStrip/Data/CollectionChange.cs b/src/Controls/BrowserTabStrip/Data/CollectionChange.cs
new file mode 100644
index 0000000..479d732
--- /dev/null
+++ b/src/Controls/BrowserTabStrip/Data/CollectionChange.cs
@@ -0,0 +1,3 @@
+namespace SharpBrowser.Controls.BrowserTabStrip {
+ public delegate void CollectionChange(int index, object value);
+}
\ No newline at end of file
diff --git a/src/Controls/BrowserTabStrip/Data/CollectionClear.cs b/src/Controls/BrowserTabStrip/Data/CollectionClear.cs
new file mode 100644
index 0000000..630c211
--- /dev/null
+++ b/src/Controls/BrowserTabStrip/Data/CollectionClear.cs
@@ -0,0 +1,3 @@
+namespace SharpBrowser.Controls.BrowserTabStrip {
+ public delegate void CollectionClear();
+}
\ No newline at end of file
diff --git a/src/Controls/BrowserTabStrip/Data/CollectionWithEvents.cs b/src/Controls/BrowserTabStrip/Data/CollectionWithEvents.cs
new file mode 100644
index 0000000..ad6919e
--- /dev/null
+++ b/src/Controls/BrowserTabStrip/Data/CollectionWithEvents.cs
@@ -0,0 +1,81 @@
+using System.Collections;
+using System.ComponentModel;
+
+namespace SharpBrowser.Controls.BrowserTabStrip {
+ public abstract class CollectionWithEvents : CollectionBase {
+ private int _suspendCount;
+
+ [Browsable(false)]
+ public bool IsSuspended => _suspendCount > 0;
+
+ [Browsable(false)]
+ public event CollectionClear Clearing;
+
+ [Browsable(false)]
+ public event CollectionClear Cleared;
+
+ [Browsable(false)]
+ public event CollectionChange Inserting;
+
+ [Browsable(false)]
+ public event CollectionChange Inserted;
+
+ [Browsable(false)]
+ public event CollectionChange Removing;
+
+ [Browsable(false)]
+ public event CollectionChange Removed;
+
+ public CollectionWithEvents() {
+ _suspendCount = 0;
+ }
+
+ public void SuspendEvents() {
+ _suspendCount++;
+ }
+
+ public void ResumeEvents() {
+ _suspendCount--;
+ }
+
+ protected override void OnClear() {
+ if (!IsSuspended && this.Clearing != null) {
+ this.Clearing();
+ }
+ }
+
+ protected override void OnClearComplete() {
+ if (!IsSuspended && this.Cleared != null) {
+ this.Cleared();
+ }
+ }
+
+ protected override void OnInsert(int index, object value) {
+ if (!IsSuspended && this.Inserting != null) {
+ this.Inserting(index, value);
+ }
+ }
+
+ protected override void OnInsertComplete(int index, object value) {
+ if (!IsSuspended && this.Inserted != null) {
+ this.Inserted(index, value);
+ }
+ }
+
+ protected override void OnRemove(int index, object value) {
+ if (!IsSuspended && this.Removing != null) {
+ this.Removing(index, value);
+ }
+ }
+
+ protected override void OnRemoveComplete(int index, object value) {
+ if (!IsSuspended && this.Removed != null) {
+ this.Removed(index, value);
+ }
+ }
+
+ protected int IndexOf(object value) {
+ return base.List.IndexOf(value);
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Controls/BrowserTabStrip/Enums/BrowserTabStripItemChangeTypes.cs b/src/Controls/BrowserTabStrip/Enums/BrowserTabStripItemChangeTypes.cs
new file mode 100644
index 0000000..bfff0fa
--- /dev/null
+++ b/src/Controls/BrowserTabStrip/Enums/BrowserTabStripItemChangeTypes.cs
@@ -0,0 +1,8 @@
+namespace SharpBrowser.Controls.BrowserTabStrip {
+ public enum BrowserTabStripItemChangeTypes {
+ Added,
+ Removed,
+ Changed,
+ SelectionChanged
+ }
+}
\ No newline at end of file
diff --git a/src/Controls/BrowserTabStrip/Enums/HitTestResult.cs b/src/Controls/BrowserTabStrip/Enums/HitTestResult.cs
new file mode 100644
index 0000000..a0f0799
--- /dev/null
+++ b/src/Controls/BrowserTabStrip/Enums/HitTestResult.cs
@@ -0,0 +1,8 @@
+namespace SharpBrowser.Controls.BrowserTabStrip {
+ public enum HitTestResult {
+ CloseButton,
+ TabItem,
+ NewButton,
+ None
+ }
+}
\ No newline at end of file
diff --git a/src/Controls/BrowserTabStrip/Events/BrowserTabStripItemChangedEventArgs.cs b/src/Controls/BrowserTabStrip/Events/BrowserTabStripItemChangedEventArgs.cs
new file mode 100644
index 0000000..163f7ea
--- /dev/null
+++ b/src/Controls/BrowserTabStrip/Events/BrowserTabStripItemChangedEventArgs.cs
@@ -0,0 +1,18 @@
+using System;
+
+namespace SharpBrowser.Controls.BrowserTabStrip {
+ public class TabStripItemChangedEventArgs : EventArgs {
+ private BrowserTabPage itm;
+
+ private BrowserTabStripItemChangeTypes changeType;
+
+ public BrowserTabStripItemChangeTypes ChangeType => changeType;
+
+ public BrowserTabPage Item => itm;
+
+ public TabStripItemChangedEventArgs(BrowserTabPage item, BrowserTabStripItemChangeTypes type) {
+ changeType = type;
+ itm = item;
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Controls/BrowserTabStrip/Events/BrowserTabStripItemChangedHandler.cs b/src/Controls/BrowserTabStrip/Events/BrowserTabStripItemChangedHandler.cs
new file mode 100644
index 0000000..83062a1
--- /dev/null
+++ b/src/Controls/BrowserTabStrip/Events/BrowserTabStripItemChangedHandler.cs
@@ -0,0 +1,3 @@
+namespace SharpBrowser.Controls.BrowserTabStrip {
+ public delegate void TabStripItemChangedHandler(TabStripItemChangedEventArgs e);
+}
\ No newline at end of file
diff --git a/src/Controls/BrowserTabStrip/Events/BrowserTabStripItemClosingEventArgs.cs b/src/Controls/BrowserTabStrip/Events/BrowserTabStripItemClosingEventArgs.cs
new file mode 100644
index 0000000..e33bb4a
--- /dev/null
+++ b/src/Controls/BrowserTabStrip/Events/BrowserTabStripItemClosingEventArgs.cs
@@ -0,0 +1,31 @@
+using System;
+
+namespace SharpBrowser.Controls.BrowserTabStrip {
+ public class TabStripItemClosingEventArgs : EventArgs {
+ private bool _cancel;
+
+ private BrowserTabPage _item;
+
+ public BrowserTabPage Item {
+ get {
+ return _item;
+ }
+ set {
+ _item = value;
+ }
+ }
+
+ public bool Cancel {
+ get {
+ return _cancel;
+ }
+ set {
+ _cancel = value;
+ }
+ }
+
+ public TabStripItemClosingEventArgs(BrowserTabPage item) {
+ _item = item;
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Controls/BrowserTabStrip/Events/BrowserTabStripItemClosingHandler.cs b/src/Controls/BrowserTabStrip/Events/BrowserTabStripItemClosingHandler.cs
new file mode 100644
index 0000000..9b09cd9
--- /dev/null
+++ b/src/Controls/BrowserTabStrip/Events/BrowserTabStripItemClosingHandler.cs
@@ -0,0 +1,3 @@
+namespace SharpBrowser.Controls.BrowserTabStrip {
+ public delegate void TabStripItemClosingHandler(TabStripItemClosingEventArgs e);
+}
\ No newline at end of file
diff --git a/src/Controls/CircularDownloadProgress.cs b/src/Controls/CircularDownloadProgress.cs
new file mode 100644
index 0000000..b118115
--- /dev/null
+++ b/src/Controls/CircularDownloadProgress.cs
@@ -0,0 +1,144 @@
+using SharpBrowser.Managers;
+using System;
+using System.Collections.Generic;
+using System.Drawing;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows.Forms;
+using static System.Windows.Forms.VisualStyles.VisualStyleElement.Rebar;
+
+namespace SharpBrowser.Controls
+{
+
+ ///
+ /// Draws Download Progress as Circle to Given Button..
+ ///
+ public class CircularDownloadProgress
+ {
+
+ public CircularDownloadProgress(Button btnDL)
+ {
+
+ init_downloads_indicator(btnDL);
+ }
+ //------ draw Circular downloading Progress
+
+ Button _btnDL;
+ public void init_downloads_indicator(Button btnDL)
+ {
+ _btnDL = btnDL;
+ btnDL.Paint += btnDL_Paint;
+ var tmr_downloader = new System.Windows.Forms.Timer();
+ tmr_downloader.Interval = 500;
+ tmr_downloader.Tick += Tmr_downloader_Tick;
+ tmr_downloader.Start();
+ }
+
+ int testdl_pct = 0;
+ private void Tmr_downloader_Tick(object sender, EventArgs e)
+ {
+
+ bool isDownloading=false;
+ bool needs_lastRefresh=false;
+ try
+ {
+ isDownloading = DownloadManager.DownloadsInProgress();
+ if (!isDownloading)
+ {
+ var curdlitemKV_val = DownloadManager.Downloads
+ .Where(x => DateTime.Now.Subtract( x.Value.EndTime ?? DateTime.MinValue).TotalSeconds <3 )
+ .Select(x=>x.Value)
+ .FirstOrDefault();
+ //var curdlitem = curdlitemKV.Value;
+ if(curdlitemKV_val != null)
+ needs_lastRefresh = true;
+ }
+ }
+ catch (Exception ex) { }
+
+ if (isDownloading || needs_lastRefresh)
+ _btnDL.Refresh();
+
+ //BtnDownloads.Invalidate();
+
+
+ //testdl_pct = testdl_pct + 10;
+ //if (testdl_pct > 100)
+ // testdl_pct = 0;
+ }
+
+ private void btnDL_Paint(object sender, PaintEventArgs e)
+ {
+ try
+ {
+ var isDownloading = DownloadManager.DownloadsInProgress();
+ float pct_ofRecentDownloadingItem = 0;
+ if (isDownloading)
+ {
+ var curdlitemKV = DownloadManager.Downloads.Where(x => x.Value.IsInProgress).FirstOrDefault();
+ var curdlitem = curdlitemKV.Value;
+ pct_ofRecentDownloadingItem = (int)(curdlitem.ReceivedBytes * 100.0f / curdlitem.TotalBytes);
+ }
+
+ //var isDownloading = true;
+ if (isDownloading)
+ {
+ //var pct1 = 100; // 100 %;
+ //var pct2 = 50; // 50 %;
+ //var pct3 =25; // 20 %;
+ var pct = testdl_pct; //test val; // <<<<---- input download percentage HERE;;
+ pct = (int)pct_ofRecentDownloadingItem;
+
+ var pctAs360val = pct / 100.0f * 360;
+ var arc_StartOffset = 90;
+
+ //Color activeColorORG = Color.FromArgb(11, 87, 208);
+ //Color activeLightColor = Color.FromArgb(76, 194, 255);
+ Color activeColor = Color.FromArgb(27, 117, 208);
+ int gray = 200;
+ var myGray = Color.FromArgb(gray, gray, gray);
+
+ //var loc = BtnDownloads.Location;
+ //var sz = BtnDownloads.Size;
+ var loc = new Point(0, 0);
+ var sz = _btnDL.ClientRectangle;
+ var pad = 0;
+ //var btng = BtnDownloads.CreateGraphics();
+
+ var thickness = 4;
+
+ var btng = e.Graphics;
+ //var btng = BtnDownloads.CreateGraphics();
+ btng.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
+
+
+ var szHW_min = Math.Min(sz.Width, sz.Height);
+ var szHW_max_minus_min = Math.Abs(sz.Width - sz.Height) / 2; //aka center it. vertical.
+ Rectangle rect = new Rectangle(
+ loc.X + pad + thickness / 2,
+ loc.Y + pad + thickness / 2,
+ szHW_min - 1 * pad - thickness / 2 * 2 - 1,
+ szHW_min - 1 * pad - thickness / 2 * 2 - 1
+ );
+
+ rect.Offset(szHW_max_minus_min, 0);
+ //sz.Width - 1 * pad - thickness / 2 * 2 - 1,
+ //sz.Height - 1 * pad - thickness / 2 * 2 - 1
+ //);
+ //btng.FillRectangle(new Pen(new SolidBrush(Color.Black), 10).Brush, rect);
+ btng.DrawArc(new Pen(new SolidBrush(myGray), thickness), rect, 0 + arc_StartOffset, 360);
+ btng.DrawArc(new Pen(new SolidBrush(activeColor), thickness), rect, 0 + arc_StartOffset, pctAs360val);
+
+ }
+ }
+ catch (Exception ex)
+ {
+ Console.WriteLine(ex + "ERROR at btnDL_Paint:");
+ }
+ }
+
+
+
+ }
+}
diff --git a/src/Data/JSON.cs b/src/Data/JSON.cs
deleted file mode 100644
index 4ee7464..0000000
--- a/src/Data/JSON.cs
+++ /dev/null
@@ -1,1997 +0,0 @@
-using System;
-using System.Collections;
-using System.Collections.Generic;
-using System.Data;
-using System.Globalization;
-using System.IO;
-using System.Text;
-using System.Reflection.Emit;
-using System.Reflection;
-using System.Data;
-using System.Xml;
-
-
-#region JSON
-
-public delegate string Serialize(object data);
-public delegate object Deserialize(string data);
-
-public class JSONParameters
-{
- ///
- /// Use the optimized fast Dataset Schema format (dfault = True)
- ///
- public bool UseOptimizedDatasetSchema = true;
- ///
- /// Use the fast GUID format (default = True)
- ///
- public bool UseFastGuid = true;
- ///
- /// Serialize null values to the output (default = True)
- ///
- public bool SerializeNullValues = true;
- ///
- /// Use the UTC date format (default = True)
- ///
- public bool UseUTCDateTime = true;
- ///
- /// Show the readonly properties of types in the output (default = False)
- ///
- public bool ShowReadOnlyProperties = false;
- ///
- /// Use the $types extension to optimise the output json (default = True)
- ///
- public bool UsingGlobalTypes = true;
- ///
- ///
- ///
- public bool IgnoreCaseOnDeserialize = false;
- ///
- /// Anonymous types have read only properties
- ///
- public bool EnableAnonymousTypes = false;
- ///
- /// Enable fastJSON extensions $types, $type, $map (default = True)
- ///
- public bool UseExtensions = true;
-}
-
-public class JSON
-{
- public readonly static JSON Instance = new JSON();
-
- private JSON()
- {
- }
- ///
- /// You can set these paramters globally for all calls
- ///
- public JSONParameters Parameters = new JSONParameters();
- private JSONParameters _params;
- // FIX : extensions off should not output $types
- public string ToJSON(object obj)
- {
- _params = Parameters;
- Reflection.Instance.ShowReadOnlyProperties = _params.ShowReadOnlyProperties;
- return ToJSON(obj, Parameters);
- }
-
- public string ToJSON(object obj, JSONParameters param)
- {
- _params = param;
- Reflection.Instance.ShowReadOnlyProperties = _params.ShowReadOnlyProperties;
- // FEATURE : enable extensions when you can deserialize anon types
- if (_params.EnableAnonymousTypes) { _params.UseExtensions = false; _params.UsingGlobalTypes = false; }
- return new JSONSerializer(param).ConvertToJSON(obj);
- }
-
- public object Parse(string json)
- {
- _params = Parameters;
- Reflection.Instance.ShowReadOnlyProperties = _params.ShowReadOnlyProperties;
- return new JsonParser(json, Parameters.IgnoreCaseOnDeserialize).Decode();
- }
-
- public T ToObject(string json)
- {
- return (T)ToObject(json, typeof(T));
- }
-
- public object ToObject(string json)
- {
- return ToObject(json, null);
- }
-
- public object ToObject(string json, Type type)
- {
- _params = Parameters;
- Reflection.Instance.ShowReadOnlyProperties = _params.ShowReadOnlyProperties;
- Dictionary ht = new JsonParser(json, Parameters.IgnoreCaseOnDeserialize).Decode() as Dictionary;
- if (ht == null) return null;
- return ParseDictionary(ht, null, type, null);
- }
-
- public string Beautify(string input)
- {
- return Formatter.PrettyPrint(input);
- }
-
- public object FillObject(object input, string json)
- {
- _params = Parameters;
- Reflection.Instance.ShowReadOnlyProperties = _params.ShowReadOnlyProperties;
- Dictionary ht = new JsonParser(json, Parameters.IgnoreCaseOnDeserialize).Decode() as Dictionary;
- if (ht == null) return null;
- return ParseDictionary(ht, null, input.GetType(), input);
- }
-
- public object DeepCopy(object obj)
- {
- return ToObject(ToJSON(obj));
- }
-
- public T DeepCopy(T obj)
- {
- return ToObject(ToJSON(obj));
- }
-
- #region [ JSON specific reflection ]
-
- private struct myPropInfo
- {
- public bool filled;
- public Type pt;
- public Type bt;
- public Type changeType;
- public bool isDictionary;
- public bool isValueType;
- public bool isGenericType;
- public bool isArray;
- public bool isByteArray;
- public bool isGuid;
- public bool isDataSet;
- public bool isDataTable;
- public bool isHashtable;
- public Reflection.GenericSetter setter;
- public bool isEnum;
- public bool isDateTime;
- public Type[] GenericTypes;
- public bool isInt;
- public bool isLong;
- public bool isString;
- public bool isBool;
- public bool isClass;
- public Reflection.GenericGetter getter;
- public bool isStringDictionary;
- public string Name;
- public bool CanWrite;
- }
-
- SafeDictionary> _propertycache = new SafeDictionary>();
- private SafeDictionary Getproperties(Type type, string typename)
- {
- SafeDictionary sd = null;
- if (_propertycache.TryGetValue(typename, out sd))
- {
- return sd;
- }
- else
- {
- sd = new SafeDictionary();
- PropertyInfo[] pr = type.GetProperties(BindingFlags.Public | BindingFlags.Instance);
- foreach (PropertyInfo p in pr)
- {
- myPropInfo d = CreateMyProp(p.PropertyType, p.Name);
- d.CanWrite = p.CanWrite;
- d.setter = Reflection.CreateSetMethod(type, p);
- d.getter = Reflection.CreateGetMethod(type, p);
- sd.Add(p.Name, d);
- }
- FieldInfo[] fi = type.GetFields(BindingFlags.Public | BindingFlags.Instance);
- foreach (FieldInfo f in fi)
- {
- myPropInfo d = CreateMyProp(f.FieldType, f.Name);
- d.setter = Reflection.CreateSetField(type, f);
- d.getter = Reflection.CreateGetField(type, f);
- sd.Add(f.Name, d);
- }
-
- _propertycache.Add(typename, sd);
- return sd;
- }
- }
-
- private myPropInfo CreateMyProp(Type t, string name)
- {
- myPropInfo d = new myPropInfo();
- d.filled = true;
- d.CanWrite = true;
- d.pt = t;
- d.Name = name;
- d.isDictionary = t.Name.Contains("Dictionary");
- if (d.isDictionary)
- d.GenericTypes = t.GetGenericArguments();
- d.isValueType = t.IsValueType;
- d.isGenericType = t.IsGenericType;
- d.isArray = t.IsArray;
- if (d.isArray)
- d.bt = t.GetElementType();
- if (d.isGenericType)
- d.bt = t.GetGenericArguments()[0];
- d.isByteArray = t == typeof(byte[]);
- d.isGuid = (t == typeof(Guid) || t == typeof(Guid?));
- d.isHashtable = t == typeof(Hashtable);
- d.isDataSet = t == typeof(DataSet);
- d.isDataTable = t == typeof(DataTable);
-
- d.changeType = GetChangeType(t);
- d.isEnum = t.IsEnum;
- d.isDateTime = t == typeof(DateTime) || t == typeof(DateTime?);
- d.isInt = t == typeof(int) || t == typeof(int?);
- d.isLong = t == typeof(long) || t == typeof(long?);
- d.isString = t == typeof(string);
- d.isBool = t == typeof(bool) || t == typeof(bool?);
- d.isClass = t.IsClass;
-
- if (d.isDictionary && d.GenericTypes.Length > 0 && d.GenericTypes[0] == typeof(string))
- d.isStringDictionary = true;
-
- return d;
- }
-
- private object ChangeType(object value, Type conversionType)
- {
- if (conversionType == typeof(int))
- return (int)CreateLong((string)value);
-
- else if (conversionType == typeof(long))
- return CreateLong((string)value);
-
- else if (conversionType == typeof(string))
- return (string)value;
-
- else if (conversionType == typeof(Guid))
- return CreateGuid((string)value);
-
- else if (conversionType.IsEnum)
- return CreateEnum(conversionType, (string)value);
-
- return Convert.ChangeType(value, conversionType, CultureInfo.InvariantCulture);
- }
- #endregion
-
- #region [ p r i v a t e m e t h o d s ]
- bool usingglobals = false;
- private object ParseDictionary(Dictionary d, Dictionary globaltypes, Type type, object input)
- {
- object tn = "";
-
- if (d.TryGetValue("$types", out tn))
- {
- usingglobals = true;
- globaltypes = new Dictionary();
- foreach (var kv in (Dictionary)tn)
- {
- globaltypes.Add((string)kv.Value, kv.Key);
- }
- }
-
- bool found = d.TryGetValue("$type", out tn);
- if (found == false && type == typeof(System.Object))
- {
- return CreateDataset(d, globaltypes);
- }
-
- if (found)
- {
- if (usingglobals)
- {
- object tname = "";
- if (globaltypes.TryGetValue((string)tn, out tname))
- tn = tname;
- }
- type = Reflection.Instance.GetTypeFromCache((string)tn);
- }
-
- if (type == null)
- throw new Exception("Cannot determine type");
-
- string typename = type.FullName;
- object o = input;
- if (o == null)
- o = Reflection.Instance.FastCreateInstance(type);
- SafeDictionary props = Getproperties(type, typename);
- foreach (string n in d.Keys)
- {
- string name = n;
- if (_params.IgnoreCaseOnDeserialize) name = name.ToLower();
- if (name == "$map")
- {
- ProcessMap(o, props, (Dictionary)d[name]);
- continue;
- }
- myPropInfo pi;
- if (props.TryGetValue(name, out pi) == false)
- continue;
- if (pi.filled == true)
- {
- object v = d[name];
-
- if (v != null)
- {
- object oset = null;
-
- if (pi.isInt)
- oset = (int)CreateLong((string)v);
-
- else if (pi.isLong)
- oset = CreateLong((string)v);
-
- else if (pi.isString)
- oset = (string)v;
-
- else if (pi.isBool)
- oset = (bool)v;
-
- else if (pi.isGenericType && pi.isValueType == false && pi.isDictionary == false)
- oset = CreateGenericList((ArrayList)v, pi.pt, pi.bt, globaltypes);
-
- else if (pi.isByteArray)
- oset = Convert.FromBase64String((string)v);
-
- else if (pi.isArray && pi.isValueType == false)
- oset = CreateArray((ArrayList)v, pi.pt, pi.bt, globaltypes);
-
- else if (pi.isGuid)
- oset = CreateGuid((string)v);
-
- else if (pi.isDataSet)
- oset = CreateDataset((Dictionary)v, globaltypes);
-
- else if (pi.isDataTable)
- oset = this.CreateDataTable((Dictionary)v, globaltypes);
-
- else if (pi.isStringDictionary)
- oset = CreateStringKeyDictionary((Dictionary)v, pi.pt, pi.GenericTypes, globaltypes);
-
- else if (pi.isDictionary || pi.isHashtable)
- oset = CreateDictionary((ArrayList)v, pi.pt, pi.GenericTypes, globaltypes);
-
- else if (pi.isEnum)
- oset = CreateEnum(pi.pt, (string)v);
-
- else if (pi.isDateTime)
- oset = CreateDateTime((string)v);
-
- else if (pi.isClass && v is Dictionary)
- oset = ParseDictionary((Dictionary)v, globaltypes, pi.pt, null);
-
- else if (pi.isValueType)
- oset = ChangeType(v, pi.changeType);
-
- else if (v is ArrayList)
- oset = CreateArray((ArrayList)v, pi.pt, typeof(object), globaltypes);
- else
- oset = v;
-
- if (pi.CanWrite)
- o = pi.setter(o, oset);
- }
- }
- }
- return o;
- }
-
- private void ProcessMap(object obj, SafeDictionary props, Dictionary dic)
- {
- foreach (KeyValuePair kv in dic)
- {
- myPropInfo p = props[kv.Key];
- object o = p.getter(obj);
- Type t = Type.GetType((string)kv.Value);
- if (t == typeof(Guid))
- p.setter(obj, CreateGuid((string)o));
- }
- }
-
- private long CreateLong(string s)
- {
- long num = 0;
- bool neg = false;
- foreach (char cc in s)
- {
- if (cc == '-')
- neg = true;
- else if (cc == '+')
- neg = false;
- else
- {
- num *= 10;
- num += (int)(cc - '0');
- }
- }
-
- return neg ? -num : num;
- }
-
- private object CreateEnum(Type pt, string v)
- {
- // TODO : optimize create enum
- return Enum.Parse(pt, v);
- }
-
- private Guid CreateGuid(string s)
- {
- if (s.Length > 30)
- return new Guid(s);
- else
- return new Guid(Convert.FromBase64String(s));
- }
-
- private DateTime CreateDateTime(string value)
- {
- bool utc = false;
- // 0123456789012345678
- // datetime format = yyyy-MM-dd HH:mm:ss
- int year = (int)CreateLong(value.Substring(0, 4));
- int month = (int)CreateLong(value.Substring(5, 2));
- int day = (int)CreateLong(value.Substring(8, 2));
- int hour = (int)CreateLong(value.Substring(11, 2));
- int min = (int)CreateLong(value.Substring(14, 2));
- int sec = (int)CreateLong(value.Substring(17, 2));
-
- if (value.EndsWith("Z"))
- utc = true;
-
- if (_params.UseUTCDateTime == false && utc == false)
- return new DateTime(year, month, day, hour, min, sec);
- else
- return new DateTime(year, month, day, hour, min, sec, DateTimeKind.Utc).ToLocalTime();
- }
-
- private object CreateArray(ArrayList data, Type pt, Type bt, Dictionary globalTypes)
- {
- ArrayList col = new ArrayList();
- // create an array of objects
- foreach (object ob in data)
- {
- if (ob is IDictionary)
- col.Add(ParseDictionary((Dictionary)ob, globalTypes, bt, null));
- else
- col.Add(ChangeType(ob, bt));
- }
- return col.ToArray(bt);
- }
-
-
- private object CreateGenericList(ArrayList data, Type pt, Type bt, Dictionary globalTypes)
- {
- IList col = (IList)Reflection.Instance.FastCreateInstance(pt);
- // create an array of objects
- foreach (object ob in data)
- {
- if (ob is IDictionary)
- col.Add(ParseDictionary((Dictionary)ob, globalTypes, bt, null));
- else if (ob is ArrayList)
- col.Add(((ArrayList)ob).ToArray());
- else
- col.Add(ChangeType(ob, bt));
- }
- return col;
- }
-
- private object CreateStringKeyDictionary(Dictionary reader, Type pt, Type[] types, Dictionary globalTypes)
- {
- var col = (IDictionary)Reflection.Instance.FastCreateInstance(pt);
- Type t1 = null;
- Type t2 = null;
- if (types != null)
- {
- t1 = types[0];
- t2 = types[1];
- }
-
- foreach (KeyValuePair values in reader)
- {
- var key = values.Key;//ChangeType(values.Key, t1);
- object val = null;
- if (values.Value is Dictionary)
- val = ParseDictionary((Dictionary)values.Value, globalTypes, t2, null);
- else
- val = ChangeType(values.Value, t2);
- col.Add(key, val);
- }
-
- return col;
- }
-
- private object CreateDictionary(ArrayList reader, Type pt, Type[] types, Dictionary globalTypes)
- {
- IDictionary col = (IDictionary)Reflection.Instance.FastCreateInstance(pt);
- Type t1 = null;
- Type t2 = null;
- if (types != null)
- {
- t1 = types[0];
- t2 = types[1];
- }
-
- foreach (Dictionary values in reader)
- {
- object key = values["k"];
- object val = values["v"];
-
- if (key is Dictionary)
- key = ParseDictionary((Dictionary)key, globalTypes, t1, null);
- else
- key = ChangeType(key, t1);
-
- if (val is Dictionary)
- val = ParseDictionary((Dictionary)val, globalTypes, t2, null);
- else
- val = ChangeType(val, t2);
-
- col.Add(key, val);
- }
-
- return col;
- }
-
- private Type GetChangeType(Type conversionType)
- {
- if (conversionType.IsGenericType && conversionType.GetGenericTypeDefinition().Equals(typeof(Nullable<>)))
- return conversionType.GetGenericArguments()[0];
-
- return conversionType;
- }
-
- private DataSet CreateDataset(Dictionary reader, Dictionary globalTypes)
- {
- DataSet ds = new DataSet();
- ds.EnforceConstraints = false;
- ds.BeginInit();
-
- // read dataset schema here
- ReadSchema(reader, ds, globalTypes);
-
- foreach (KeyValuePair pair in reader)
- {
- if (pair.Key == "$type" || pair.Key == "$schema") continue;
-
- ArrayList rows = (ArrayList)pair.Value;
- if (rows == null) continue;
-
- DataTable dt = ds.Tables[pair.Key];
- ReadDataTable(rows, dt);
- }
-
- ds.EndInit();
-
- return ds;
- }
-
- private void ReadSchema(Dictionary reader, DataSet ds, Dictionary globalTypes)
- {
- var schema = reader["$schema"];
-
- if (schema is string)
- {
- TextReader tr = new StringReader((string)schema);
- ds.ReadXmlSchema(tr);
- }
- else
- {
- DatasetSchema ms = (DatasetSchema)ParseDictionary((Dictionary)schema, globalTypes, typeof(DatasetSchema), null);
- ds.DataSetName = ms.Name;
- for (int i = 0; i < ms.Info.Count; i += 3)
- {
- if (ds.Tables.Contains(ms.Info[i]) == false)
- ds.Tables.Add(ms.Info[i]);
- ds.Tables[ms.Info[i]].Columns.Add(ms.Info[i + 1], Type.GetType(ms.Info[i + 2]));
- }
- }
- }
-
- private void ReadDataTable(ArrayList rows, DataTable dt)
- {
- dt.BeginInit();
- dt.BeginLoadData();
- List guidcols = new List();
- List datecol = new List();
-
- foreach (DataColumn c in dt.Columns)
- {
- if (c.DataType == typeof(Guid) || c.DataType == typeof(Guid?))
- guidcols.Add(c.Ordinal);
- if (_params.UseUTCDateTime && (c.DataType == typeof(DateTime) || c.DataType == typeof(DateTime?)))
- datecol.Add(c.Ordinal);
- }
-
- foreach (ArrayList row in rows)
- {
- object[] v = new object[row.Count];
- row.CopyTo(v, 0);
- foreach (int i in guidcols)
- {
- string s = (string)v[i];
- if (s != null && s.Length < 36)
- v[i] = new Guid(Convert.FromBase64String(s));
- }
- if (_params.UseUTCDateTime)
- {
- foreach (int i in datecol)
- {
- string s = (string)v[i];
- if (s != null)
- v[i] = CreateDateTime(s);
- }
- }
- dt.Rows.Add(v);
- }
-
- dt.EndLoadData();
- dt.EndInit();
- }
-
- DataTable CreateDataTable(Dictionary reader, Dictionary globalTypes)
- {
- var dt = new DataTable();
-
- // read dataset schema here
- var schema = reader["$schema"];
-
- if (schema is string)
- {
- TextReader tr = new StringReader((string)schema);
- dt.ReadXmlSchema(tr);
- }
- else
- {
- var ms = (DatasetSchema)this.ParseDictionary((Dictionary)schema, globalTypes, typeof(DatasetSchema), null);
- dt.TableName = ms.Info[0];
- for (int i = 0; i < ms.Info.Count; i += 3)
- {
- dt.Columns.Add(ms.Info[i + 1], Type.GetType(ms.Info[i + 2]));
- }
- }
-
- foreach (var pair in reader)
- {
- if (pair.Key == "$type" || pair.Key == "$schema")
- continue;
-
- var rows = (ArrayList)pair.Value;
- if (rows == null)
- continue;
-
- if (!dt.TableName.Equals(pair.Key, StringComparison.InvariantCultureIgnoreCase))
- continue;
-
- ReadDataTable(rows, dt);
- }
-
- return dt;
- }
-
- #endregion
-}
-
-#endregion
-
-
-
-
-
-#region Serializer
-internal class JSONSerializer
-{
- private readonly StringBuilder _output = new StringBuilder();
- readonly int _MAX_DEPTH = 10;
- int _current_depth = 0;
- private Dictionary _globalTypes = new Dictionary();
- private JSONParameters _params;
-
- internal JSONSerializer(JSONParameters param)
- {
- _params = param;
- }
-
- internal string ConvertToJSON(object obj)
- {
- WriteValue(obj);
-
- string str = "";
- if (_params.UsingGlobalTypes)
- {
- StringBuilder sb = new StringBuilder();
- sb.Append("\"$types\":{");
- bool pendingSeparator = false;
- foreach (var kv in _globalTypes)
- {
- if (pendingSeparator) sb.Append(',');
- pendingSeparator = true;
- sb.Append("\"");
- sb.Append(kv.Key);
- sb.Append("\":\"");
- sb.Append(kv.Value);
- sb.Append("\"");
- }
- sb.Append("},");
- str = _output.Replace("$types$", sb.ToString()).ToString();
- }
- else
- str = _output.ToString();
-
- return str;
- }
-
- private void WriteValue(object obj)
- {
- if (obj == null || obj is DBNull)
- _output.Append("null");
-
- else if (obj is string || obj is char)
- WriteString(obj.ToString());
-
- else if (obj is Guid)
- WriteGuid((Guid)obj);
-
- else if (obj is bool)
- _output.Append(((bool)obj) ? "true" : "false"); // conform to standard
-
- else if (
- obj is int || obj is long || obj is double ||
- obj is decimal || obj is float ||
- obj is byte || obj is short ||
- obj is sbyte || obj is ushort ||
- obj is uint || obj is ulong
- )
- _output.Append(((IConvertible)obj).ToString(NumberFormatInfo.InvariantInfo));
-
- else if (obj is DateTime)
- WriteDateTime((DateTime)obj);
-
- else if (obj is IDictionary && obj.GetType().IsGenericType && obj.GetType().GetGenericArguments()[0] == typeof(string))
- WriteStringDictionary((IDictionary)obj);
-
- else if (obj is IDictionary)
- WriteDictionary((IDictionary)obj);
-
- else if (obj is DataSet)
- WriteDataset((DataSet)obj);
-
- else if (obj is DataTable)
- this.WriteDataTable((DataTable)obj);
-
- else if (obj is byte[])
- WriteBytes((byte[])obj);
-
- else if (obj is Array || obj is IList || obj is ICollection)
- WriteArray((IEnumerable)obj);
-
- else if (obj is Enum)
- WriteEnum((Enum)obj);
-
- else
- WriteObject(obj);
- }
-
- private void WriteEnum(Enum e)
- {
- // TODO : optimize enum write
- WriteStringFast(e.ToString());
- }
-
- private void WriteGuid(Guid g)
- {
- if (_params.UseFastGuid == false)
- WriteStringFast(g.ToString());
- else
- WriteBytes(g.ToByteArray());
- }
-
- private void WriteBytes(byte[] bytes)
- {
- WriteStringFast(Convert.ToBase64String(bytes, 0, bytes.Length, Base64FormattingOptions.None));
- }
-
- private void WriteDateTime(DateTime dateTime)
- {
- // datetime format standard : yyyy-MM-dd HH:mm:ss
- DateTime dt = dateTime;
- if (_params.UseUTCDateTime)
- dt = dateTime.ToUniversalTime();
-
- _output.Append("\"");
- _output.Append(dt.Year.ToString("0000", NumberFormatInfo.InvariantInfo));
- _output.Append("-");
- _output.Append(dt.Month.ToString("00", NumberFormatInfo.InvariantInfo));
- _output.Append("-");
- _output.Append(dt.Day.ToString("00", NumberFormatInfo.InvariantInfo));
- _output.Append(" ");
- _output.Append(dt.Hour.ToString("00", NumberFormatInfo.InvariantInfo));
- _output.Append(":");
- _output.Append(dt.Minute.ToString("00", NumberFormatInfo.InvariantInfo));
- _output.Append(":");
- _output.Append(dt.Second.ToString("00", NumberFormatInfo.InvariantInfo));
-
- if (_params.UseUTCDateTime)
- _output.Append("Z");
-
- _output.Append("\"");
- }
- private DatasetSchema GetSchema(DataTable ds)
- {
- if (ds == null) return null;
-
- DatasetSchema m = new DatasetSchema();
- m.Info = new List();
- m.Name = ds.TableName;
-
- foreach (DataColumn c in ds.Columns)
- {
- m.Info.Add(ds.TableName);
- m.Info.Add(c.ColumnName);
- m.Info.Add(c.DataType.ToString());
- }
- // FEATURE : serialize relations and constraints here
-
- return m;
- }
-
- private DatasetSchema GetSchema(DataSet ds)
- {
- if (ds == null) return null;
-
- DatasetSchema m = new DatasetSchema();
- m.Info = new List();
- m.Name = ds.DataSetName;
-
- foreach (DataTable t in ds.Tables)
- {
- foreach (DataColumn c in t.Columns)
- {
- m.Info.Add(t.TableName);
- m.Info.Add(c.ColumnName);
- m.Info.Add(c.DataType.ToString());
- }
- }
- // FEATURE : serialize relations and constraints here
-
- return m;
- }
-
- private string GetXmlSchema(DataTable dt)
- {
- using (var writer = new StringWriter())
- {
- dt.WriteXmlSchema(writer);
- return dt.ToString();
- }
- }
-
- private void WriteDataset(DataSet ds)
- {
- _output.Append('{');
- if ( _params.UseExtensions)
- {
- WritePair("$schema", _params.UseOptimizedDatasetSchema ? (object)GetSchema(ds) : ds.GetXmlSchema());
- _output.Append(',');
- }
- bool tablesep = false;
- foreach (DataTable table in ds.Tables)
- {
- if (tablesep) _output.Append(",");
- tablesep = true;
- WriteDataTableData(table);
- }
- // end dataset
- _output.Append('}');
- }
-
- private void WriteDataTableData(DataTable table)
- {
- _output.Append('\"');
- _output.Append(table.TableName);
- _output.Append("\":[");
- DataColumnCollection cols = table.Columns;
- bool rowseparator = false;
- foreach (DataRow row in table.Rows)
- {
- if (rowseparator) _output.Append(",");
- rowseparator = true;
- _output.Append('[');
-
- bool pendingSeperator = false;
- foreach (DataColumn column in cols)
- {
- if (pendingSeperator) _output.Append(',');
- WriteValue(row[column]);
- pendingSeperator = true;
- }
- _output.Append(']');
- }
-
- _output.Append(']');
- }
-
- void WriteDataTable(DataTable dt)
- {
- this._output.Append('{');
- if (_params.UseExtensions)
- {
- this.WritePair("$schema", _params.UseOptimizedDatasetSchema ? (object)this.GetSchema(dt) : this.GetXmlSchema(dt));
- this._output.Append(',');
- }
-
- WriteDataTableData(dt);
-
- // end datatable
- this._output.Append('}');
- }
- bool _TypesWritten = false;
- private void WriteObject(object obj)
- {
- if (_params.UsingGlobalTypes == false)
- _output.Append('{');
- else
- {
- if (_TypesWritten== false)
- _output.Append("{$types$");
- else
- _output.Append("{");
- }
- _TypesWritten = true;
- _current_depth++;
- if (_current_depth > _MAX_DEPTH)
- throw new Exception("Serializer encountered maximum depth of " + _MAX_DEPTH);
-
-
- Dictionary map = new Dictionary();
- Type t = obj.GetType();
- bool append = false;
- if (_params.UseExtensions)
- {
- if (_params.UsingGlobalTypes == false)
- WritePairFast("$type", Reflection.Instance.GetTypeAssemblyName(t));
- else
- {
- int dt = 0;
- string ct = Reflection.Instance.GetTypeAssemblyName(t);
- if (_globalTypes.TryGetValue(ct, out dt) == false)
- {
- dt = _globalTypes.Count + 1;
- _globalTypes.Add(ct, dt);
- }
- WritePairFast("$type", dt.ToString());
- }
- append = true;
- }
-
- List g = Reflection.Instance.GetGetters(t);
- foreach (var p in g)
- {
- if (append)
- _output.Append(',');
- object o = p.Getter(obj);
- if ((o == null || o is DBNull) && _params.SerializeNullValues == false)
- append = false;
- else
- {
- WritePair(p.Name, o);
- if (o != null && _params.UseExtensions)
- {
- Type tt = o.GetType();
- if (tt == typeof(System.Object))
- map.Add(p.Name, tt.ToString());
- }
- append = true;
- }
- }
- if (map.Count > 0 && _params.UseExtensions)
- {
- _output.Append(",\"$map\":");
- WriteStringDictionary(map);
- }
- _current_depth--;
- _output.Append('}');
- _current_depth--;
-
- }
-
- private void WritePairFast(string name, string value)
- {
- if ((value == null) && _params.SerializeNullValues == false)
- return;
- WriteStringFast(name);
-
- _output.Append(':');
-
- WriteStringFast(value);
- }
-
- private void WritePair(string name, object value)
- {
- if ((value == null || value is DBNull) && _params.SerializeNullValues == false)
- return;
- WriteStringFast(name);
-
- _output.Append(':');
-
- WriteValue(value);
- }
-
- private void WriteArray(IEnumerable array)
- {
- _output.Append('[');
-
- bool pendingSeperator = false;
-
- foreach (object obj in array)
- {
- if (pendingSeperator) _output.Append(',');
-
- WriteValue(obj);
-
- pendingSeperator = true;
- }
- _output.Append(']');
- }
-
- private void WriteStringDictionary(IDictionary dic)
- {
- _output.Append('{');
-
- bool pendingSeparator = false;
-
- foreach (DictionaryEntry entry in dic)
- {
- if (pendingSeparator) _output.Append(',');
-
- WritePair((string)entry.Key, entry.Value);
-
- pendingSeparator = true;
- }
- _output.Append('}');
- }
-
- private void WriteDictionary(IDictionary dic)
- {
- _output.Append('[');
-
- bool pendingSeparator = false;
-
- foreach (DictionaryEntry entry in dic)
- {
- if (pendingSeparator) _output.Append(',');
- _output.Append('{');
- WritePair("k", entry.Key);
- _output.Append(",");
- WritePair("v", entry.Value);
- _output.Append('}');
-
- pendingSeparator = true;
- }
- _output.Append(']');
- }
-
- private void WriteStringFast(string s)
- {
- _output.Append('\"');
- _output.Append(s);
- _output.Append('\"');
- }
-
- private void WriteString(string s)
- {
- _output.Append('\"');
-
- int runIndex = -1;
-
- for (var index = 0; index < s.Length; ++index)
- {
- var c = s[index];
-
- if (c >= ' ' && c < 128 && c != '\"' && c != '\\')
- {
- if (runIndex == -1)
- {
- runIndex = index;
- }
-
- continue;
- }
-
- if (runIndex != -1)
- {
- _output.Append(s, runIndex, index - runIndex);
- runIndex = -1;
- }
-
- switch (c)
- {
- case '\t': _output.Append("\\t"); break;
- case '\r': _output.Append("\\r"); break;
- case '\n': _output.Append("\\n"); break;
- case '"':
- case '\\': _output.Append('\\'); _output.Append(c); break;
- default:
- _output.Append("\\u");
- _output.Append(((int)c).ToString("X4", NumberFormatInfo.InvariantInfo));
- break;
- }
- }
-
- if (runIndex != -1)
- {
- _output.Append(s, runIndex, s.Length - runIndex);
- }
-
- _output.Append('\"');
- }
-}
-
-
-#endregion
-
-
-
-
-
-#region Reflection
-internal class Getters
-{
- public string Name;
- public Reflection.GenericGetter Getter;
- public Type propertyType;
-}
-
-internal class Reflection
-{
- public readonly static Reflection Instance = new Reflection();
- private Reflection()
- {
- }
-
- public bool ShowReadOnlyProperties = false;
- internal delegate object GenericSetter(object target, object value);
- internal delegate object GenericGetter(object obj);
- private delegate object CreateObject();
-
- private SafeDictionary _tyname = new SafeDictionary();
- private SafeDictionary _typecache = new SafeDictionary();
- private SafeDictionary _constrcache = new SafeDictionary();
- private SafeDictionary> _getterscache = new SafeDictionary>();
-
- #region [ PROPERTY GET SET ]
- internal string GetTypeAssemblyName(Type t)
- {
- string val = "";
- if (_tyname.TryGetValue(t, out val))
- return val;
- else
- {
- string s = t.AssemblyQualifiedName;
- _tyname.Add(t, s);
- return s;
- }
- }
-
- internal Type GetTypeFromCache(string typename)
- {
- Type val = null;
- if (_typecache.TryGetValue(typename, out val))
- return val;
- else
- {
- Type t = Type.GetType(typename);
- _typecache.Add(typename, t);
- return t;
- }
- }
-
- internal object FastCreateInstance(Type objtype)
- {
- try
- {
- CreateObject c = null;
- if (_constrcache.TryGetValue(objtype, out c))
- {
- return c();
- }
- else
- {
- DynamicMethod dynMethod = new DynamicMethod("_",
- MethodAttributes.Public | MethodAttributes.Static,
- CallingConventions.Standard,
- typeof(object),
- null,
- objtype, false);
- ILGenerator ilGen = dynMethod.GetILGenerator();
-
- if (objtype.IsClass)
- {
- ilGen.Emit(OpCodes.Newobj, objtype.GetConstructor(Type.EmptyTypes));
- ilGen.Emit(OpCodes.Ret);
- c = (CreateObject)dynMethod.CreateDelegate(typeof(CreateObject));
- _constrcache.Add(objtype, c);
- }
- else // structs
- {
- var lv = ilGen.DeclareLocal(objtype);
- ilGen.Emit(OpCodes.Ldloca_S, lv);
- ilGen.Emit(OpCodes.Initobj, objtype);
- ilGen.Emit(OpCodes.Ldloc_0);
- ilGen.Emit(OpCodes.Box, objtype);
- ilGen.Emit(OpCodes.Ret);
- c = (CreateObject)dynMethod.CreateDelegate(typeof(CreateObject));
- _constrcache.Add(objtype, c);
- }
- return c();
- }
- }
- catch (Exception exc)
- {
- throw new Exception(string.Format("Failed to fast create instance for type '{0}' from assemebly '{1}'",
- objtype.FullName, objtype.AssemblyQualifiedName), exc);
- }
- }
-
- internal static GenericSetter CreateSetField(Type type, FieldInfo fieldInfo)
- {
- Type[] arguments = new Type[2];
- arguments[0] = arguments[1] = typeof(object);
-
- DynamicMethod dynamicSet = new DynamicMethod("_", typeof(object), arguments, type, true);
- ILGenerator il = dynamicSet.GetILGenerator();
-
- if (!type.IsClass) // structs
- {
- var lv = il.DeclareLocal(type);
- il.Emit(OpCodes.Ldarg_0);
- il.Emit(OpCodes.Unbox_Any, type);
- il.Emit(OpCodes.Stloc_0);
- il.Emit(OpCodes.Ldloca_S, lv);
- il.Emit(OpCodes.Ldarg_1);
- if (fieldInfo.FieldType.IsClass)
- il.Emit(OpCodes.Castclass, fieldInfo.FieldType);
- else
- il.Emit(OpCodes.Unbox_Any, fieldInfo.FieldType);
- il.Emit(OpCodes.Stfld, fieldInfo);
- il.Emit(OpCodes.Ldloc_0);
- il.Emit(OpCodes.Box, type);
- il.Emit(OpCodes.Ret);
- }
- else
- {
- il.Emit(OpCodes.Ldarg_0);
- il.Emit(OpCodes.Ldarg_1);
- if (fieldInfo.FieldType.IsValueType)
- il.Emit(OpCodes.Unbox_Any, fieldInfo.FieldType);
- il.Emit(OpCodes.Stfld, fieldInfo);
- il.Emit(OpCodes.Ldarg_0);
- il.Emit(OpCodes.Ret);
- }
- return (GenericSetter)dynamicSet.CreateDelegate(typeof(GenericSetter));
- }
-
- internal static GenericSetter CreateSetMethod(Type type, PropertyInfo propertyInfo)
- {
- MethodInfo setMethod = propertyInfo.GetSetMethod();
- if (setMethod == null)
- return null;
-
- Type[] arguments = new Type[2];
- arguments[0] = arguments[1] = typeof(object);
-
- DynamicMethod setter = new DynamicMethod("_", typeof(object), arguments, type);
- ILGenerator il = setter.GetILGenerator();
-
- if (!type.IsClass) // structs
- {
- var lv = il.DeclareLocal(type);
- il.Emit(OpCodes.Ldarg_0);
- il.Emit(OpCodes.Unbox_Any, type);
- il.Emit(OpCodes.Stloc_0);
- il.Emit(OpCodes.Ldloca_S, lv);
- il.Emit(OpCodes.Ldarg_1);
- if (propertyInfo.PropertyType.IsClass)
- il.Emit(OpCodes.Castclass, propertyInfo.PropertyType);
- else
- il.Emit(OpCodes.Unbox_Any, propertyInfo.PropertyType);
- il.EmitCall(OpCodes.Call, setMethod, null);
- il.Emit(OpCodes.Ldloc_0);
- il.Emit(OpCodes.Box, type);
- }
- else
- {
- il.Emit(OpCodes.Ldarg_0);
- il.Emit(OpCodes.Castclass, propertyInfo.DeclaringType);
- il.Emit(OpCodes.Ldarg_1);
- if (propertyInfo.PropertyType.IsClass)
- il.Emit(OpCodes.Castclass, propertyInfo.PropertyType);
- else
- il.Emit(OpCodes.Unbox_Any, propertyInfo.PropertyType);
- il.EmitCall(OpCodes.Callvirt, setMethod, null);
- il.Emit(OpCodes.Ldarg_0);
- }
-
- il.Emit(OpCodes.Ret);
-
- return (GenericSetter)setter.CreateDelegate(typeof(GenericSetter));
- }
-
- internal static GenericGetter CreateGetField(Type type, FieldInfo fieldInfo)
- {
- DynamicMethod dynamicGet = new DynamicMethod("_", typeof(object), new Type[] { typeof(object) }, type, true);
- ILGenerator il = dynamicGet.GetILGenerator();
-
- if (!type.IsClass) // structs
- {
- var lv = il.DeclareLocal(type);
- il.Emit(OpCodes.Ldarg_0);
- il.Emit(OpCodes.Unbox_Any, type);
- il.Emit(OpCodes.Stloc_0);
- il.Emit(OpCodes.Ldloca_S, lv);
- il.Emit(OpCodes.Ldfld, fieldInfo);
- if (fieldInfo.FieldType.IsValueType)
- il.Emit(OpCodes.Box, fieldInfo.FieldType);
- }
- else
- {
- il.Emit(OpCodes.Ldarg_0);
- il.Emit(OpCodes.Ldfld, fieldInfo);
- if (fieldInfo.FieldType.IsValueType)
- il.Emit(OpCodes.Box, fieldInfo.FieldType);
- }
-
- il.Emit(OpCodes.Ret);
-
- return (GenericGetter)dynamicGet.CreateDelegate(typeof(GenericGetter));
- }
-
- internal static GenericGetter CreateGetMethod(Type type, PropertyInfo propertyInfo)
- {
- MethodInfo getMethod = propertyInfo.GetGetMethod();
- if (getMethod == null)
- return null;
-
- Type[] arguments = new Type[1];
- arguments[0] = typeof(object);
-
- DynamicMethod getter = new DynamicMethod("_", typeof(object), arguments, type);
- ILGenerator il = getter.GetILGenerator();
-
- if (!type.IsClass) // structs
- {
- var lv = il.DeclareLocal(type);
- il.Emit(OpCodes.Ldarg_0);
- il.Emit(OpCodes.Unbox_Any, type);
- il.Emit(OpCodes.Stloc_0);
- il.Emit(OpCodes.Ldloca_S, lv);
- il.EmitCall(OpCodes.Call, getMethod, null);
- if (propertyInfo.PropertyType.IsValueType)
- il.Emit(OpCodes.Box, propertyInfo.PropertyType);
- }
- else
- {
- il.Emit(OpCodes.Ldarg_0);
- il.Emit(OpCodes.Castclass, propertyInfo.DeclaringType);
- il.EmitCall(OpCodes.Callvirt, getMethod, null);
- if (propertyInfo.PropertyType.IsValueType)
- il.Emit(OpCodes.Box, propertyInfo.PropertyType);
- }
-
- il.Emit(OpCodes.Ret);
-
- return (GenericGetter)getter.CreateDelegate(typeof(GenericGetter));
- }
-
- internal List GetGetters(Type type)
- {
- List val = null;
- if (_getterscache.TryGetValue(type, out val))
- return val;
-
- PropertyInfo[] props = type.GetProperties(BindingFlags.Public | BindingFlags.Instance);
- List getters = new List();
- foreach (PropertyInfo p in props)
- {
- if (!p.CanWrite && ShowReadOnlyProperties == false) continue;
-
- object[] att = p.GetCustomAttributes(typeof(System.Xml.Serialization.XmlIgnoreAttribute), false);
- if (att != null && att.Length > 0)
- continue;
-
- GenericGetter g = CreateGetMethod(type, p);
- if (g != null)
- {
- Getters gg = new Getters();
- gg.Name = p.Name;
- gg.Getter = g;
- gg.propertyType = p.PropertyType;
- getters.Add(gg);
- }
- }
-
- FieldInfo[] fi = type.GetFields(BindingFlags.Instance | BindingFlags.Public);
- foreach (var f in fi)
- {
- object[] att = f.GetCustomAttributes(typeof(System.Xml.Serialization.XmlIgnoreAttribute), false);
- if (att != null && att.Length > 0)
- continue;
-
- GenericGetter g = CreateGetField(type, f);
- if (g != null)
- {
- Getters gg = new Getters();
- gg.Name = f.Name;
- gg.Getter = g;
- gg.propertyType = f.FieldType;
- getters.Add(gg);
- }
- }
-
- _getterscache.Add(type, getters);
- return getters;
- }
-
- #endregion
-}
- #endregion
-
-
-
-
-
- #region SafeDictionary
-internal class SafeDictionary
-{
- private readonly object _Padlock = new object();
- private readonly Dictionary _Dictionary;
-
- public SafeDictionary(int capacity)
- {
- _Dictionary = new Dictionary(capacity);
- }
-
- public SafeDictionary()
- {
- _Dictionary = new Dictionary();
- }
-
- public bool TryGetValue(TKey key, out TValue value)
- {
- lock (_Padlock)
- return _Dictionary.TryGetValue(key, out value);
- }
-
- public TValue this[TKey key]
- {
- get
- {
- lock (_Padlock)
- return _Dictionary[key];
- }
- set
- {
- lock (_Padlock)
- _Dictionary[key] = value;
- }
- }
-
- public void Add(TKey key, TValue value)
- {
- lock (_Padlock)
- {
- if (_Dictionary.ContainsKey(key) == false)
- _Dictionary.Add(key, value);
- }
- }
-}
-#endregion
-
-
-
-
-#region Formatter
-internal static class Formatter
-{
- public static string Indent = " ";
-
- public static void AppendIndent(StringBuilder sb, int count)
- {
- for (; count > 0; --count) sb.Append(Indent);
- }
-
- public static bool IsEscaped(StringBuilder sb, int index)
- {
- bool escaped = false;
- while (index > 0 && sb[--index] == '\\') escaped = !escaped;
- return escaped;
- }
-
- public static string PrettyPrint(string input)
- {
- var output = new StringBuilder(input.Length * 2);
- char? quote = null;
- int depth = 0;
-
- for (int i = 0; i < input.Length; ++i)
- {
- char ch = input[i];
-
- switch (ch)
- {
- case '{':
- case '[':
- output.Append(ch);
- if (!quote.HasValue)
- {
- output.AppendLine();
- AppendIndent(output, ++depth);
- }
- break;
- case '}':
- case ']':
- if (quote.HasValue)
- output.Append(ch);
- else
- {
- output.AppendLine();
- AppendIndent(output, --depth);
- output.Append(ch);
- }
- break;
- case '"':
- case '\'':
- output.Append(ch);
- if (quote.HasValue)
- {
- if (!IsEscaped(output, i))
- quote = null;
- }
- else quote = ch;
- break;
- case ',':
- output.Append(ch);
- if (!quote.HasValue)
- {
- output.AppendLine();
- AppendIndent(output, depth);
- }
- break;
- case ':':
- if (quote.HasValue) output.Append(ch);
- else output.Append(" : ");
- break;
- default:
- if (quote.HasValue || !char.IsWhiteSpace(ch))
- output.Append(ch);
- break;
- }
- }
-
- return output.ToString();
- }
-}
-#endregion
-
-
-
-
-#region Getters
- public class DatasetSchema
-{
- public List Info { get; set; }
- public string Name { get; set; }
-}
-#endregion
-
-
-
-
-
-
-#region Parser
-
-///
-/// This class encodes and decodes JSON strings.
-/// Spec. details, see http://www.json.org/
-///
-/// JSON uses Arrays and Objects. These correspond here to the datatypes ArrayList and Hashtable.
-/// All numbers are parsed to doubles.
-///
-internal class JsonParser
-{
- enum Token
- {
- None = -1, // Used to denote no Lookahead available
- Curly_Open,
- Curly_Close,
- Squared_Open,
- Squared_Close,
- Colon,
- Comma,
- String,
- Number,
- True,
- False,
- Null
- }
-
- readonly char[] json;
- readonly StringBuilder s = new StringBuilder();
- Token lookAheadToken = Token.None;
- int index;
- bool _ignorecase = false;
-
-
- internal JsonParser(string json, bool ignorecase)
- {
- this.json = json.ToCharArray();
- _ignorecase = ignorecase;
- }
-
- public object Decode()
- {
- return ParseValue();
- }
-
- private Dictionary ParseObject()
- {
- Dictionary table = new Dictionary();
-
- ConsumeToken(); // {
-
- while (true)
- {
- switch (LookAhead())
- {
-
- case Token.Comma:
- ConsumeToken();
- break;
-
- case Token.Curly_Close:
- ConsumeToken();
- return table;
-
- default:
- {
-
- // name
- string name = ParseString();
- if (_ignorecase)
- name = name.ToLower();
-
- // :
- if (NextToken() != Token.Colon)
- {
- throw new Exception("Expected colon at index " + index);
- }
-
- // value
- object value = ParseValue();
-
- table[name] = value;
- }
- break;
- }
- }
- }
-
- private ArrayList ParseArray()
- {
- ArrayList array = new ArrayList();
-
- ConsumeToken(); // [
-
- while (true)
- {
- switch (LookAhead())
- {
-
- case Token.Comma:
- ConsumeToken();
- break;
-
- case Token.Squared_Close:
- ConsumeToken();
- return array;
-
- default:
- {
- array.Add(ParseValue());
- }
- break;
- }
- }
- }
-
- private object ParseValue()
- {
- switch (LookAhead())
- {
- case Token.Number:
- return ParseNumber();
-
- case Token.String:
- return ParseString();
-
- case Token.Curly_Open:
- return ParseObject();
-
- case Token.Squared_Open:
- return ParseArray();
-
- case Token.True:
- ConsumeToken();
- return true;
-
- case Token.False:
- ConsumeToken();
- return false;
-
- case Token.Null:
- ConsumeToken();
- return null;
- }
-
- throw new Exception("Unrecognized token at index" + index);
- }
-
- private string ParseString()
- {
- ConsumeToken(); // "
-
- s.Length = 0;
-
- int runIndex = -1;
-
- while (index < json.Length)
- {
- var c = json[index++];
-
- if (c == '"')
- {
- if (runIndex != -1)
- {
- if (s.Length == 0)
- return new string(json, runIndex, index - runIndex - 1);
-
- s.Append(json, runIndex, index - runIndex - 1);
- }
- return s.ToString();
- }
-
- if (c != '\\')
- {
- if (runIndex == -1)
- runIndex = index - 1;
-
- continue;
- }
-
- if (index == json.Length) break;
-
- if (runIndex != -1)
- {
- s.Append(json, runIndex, index - runIndex - 1);
- runIndex = -1;
- }
-
- switch (json[index++])
- {
- case '"':
- s.Append('"');
- break;
-
- case '\\':
- s.Append('\\');
- break;
-
- case '/':
- s.Append('/');
- break;
-
- case 'b':
- s.Append('\b');
- break;
-
- case 'f':
- s.Append('\f');
- break;
-
- case 'n':
- s.Append('\n');
- break;
-
- case 'r':
- s.Append('\r');
- break;
-
- case 't':
- s.Append('\t');
- break;
-
- case 'u':
- {
- int remainingLength = json.Length - index;
- if (remainingLength < 4) break;
-
- // parse the 32 bit hex into an integer codepoint
- uint codePoint = ParseUnicode(json[index], json[index + 1], json[index + 2], json[index + 3]);
- s.Append((char)codePoint);
-
- // skip 4 chars
- index += 4;
- }
- break;
- }
- }
-
- throw new Exception("Unexpectedly reached end of string");
- }
-
- private uint ParseSingleChar(char c1, uint multipliyer)
- {
- uint p1 = 0;
- if (c1 >= '0' && c1 <= '9')
- p1 = (uint)(c1 - '0') * multipliyer;
- else if (c1 >= 'A' && c1 <= 'F')
- p1 = (uint)((c1 - 'A') + 10) * multipliyer;
- else if (c1 >= 'a' && c1 <= 'f')
- p1 = (uint)((c1 - 'a') + 10) * multipliyer;
- return p1;
- }
-
- private uint ParseUnicode(char c1, char c2, char c3, char c4)
- {
- uint p1 = ParseSingleChar(c1, 0x1000);
- uint p2 = ParseSingleChar(c2, 0x100);
- uint p3 = ParseSingleChar(c3, 0x10);
- uint p4 = ParseSingleChar(c4, 1);
-
- return p1 + p2 + p3 + p4;
- }
-
- private string ParseNumber()
- {
- ConsumeToken();
-
- // Need to start back one place because the first digit is also a token and would have been consumed
- var startIndex = index - 1;
-
- do
- {
- var c = json[index];
-
- if ((c >= '0' && c <= '9') || c == '.' || c == '-' || c == '+' || c == 'e' || c == 'E')
- {
- if (++index == json.Length) throw new Exception("Unexpected end of string whilst parsing number");
- continue;
- }
-
- break;
- } while (true);
-
- return new string(json, startIndex, index - startIndex);
- }
-
- private Token LookAhead()
- {
- if (lookAheadToken != Token.None) return lookAheadToken;
-
- return lookAheadToken = NextTokenCore();
- }
-
- private void ConsumeToken()
- {
- lookAheadToken = Token.None;
- }
-
- private Token NextToken()
- {
- var result = lookAheadToken != Token.None ? lookAheadToken : NextTokenCore();
-
- lookAheadToken = Token.None;
-
- return result;
- }
-
- private Token NextTokenCore()
- {
- char c;
-
- // Skip past whitespace
- do
- {
- c = json[index];
-
- if (c > ' ') break;
- if (c != ' ' && c != '\t' && c != '\n' && c != '\r') break;
-
- } while (++index < json.Length);
-
- if (index == json.Length)
- {
- throw new Exception("Reached end of string unexpectedly");
- }
-
- c = json[index];
-
- index++;
-
- //if (c >= '0' && c <= '9')
- // return Token.Number;
-
- switch (c)
- {
- case '{':
- return Token.Curly_Open;
-
- case '}':
- return Token.Curly_Close;
-
- case '[':
- return Token.Squared_Open;
-
- case ']':
- return Token.Squared_Close;
-
- case ',':
- return Token.Comma;
-
- case '"':
- return Token.String;
-
- case '0': case '1': case '2': case '3': case '4':
- case '5': case '6': case '7': case '8': case '9':
- case '-': case '+': case '.':
- return Token.Number;
-
- case ':':
- return Token.Colon;
-
- case 'f':
- if (json.Length - index >= 4 &&
- json[index + 0] == 'a' &&
- json[index + 1] == 'l' &&
- json[index + 2] == 's' &&
- json[index + 3] == 'e')
- {
- index += 4;
- return Token.False;
- }
- break;
-
- case 't':
- if (json.Length - index >= 3 &&
- json[index + 0] == 'r' &&
- json[index + 1] == 'u' &&
- json[index + 2] == 'e')
- {
- index += 3;
- return Token.True;
- }
- break;
-
- case 'n':
- if (json.Length - index >= 3 &&
- json[index + 0] == 'u' &&
- json[index + 1] == 'l' &&
- json[index + 2] == 'l')
- {
- index += 3;
- return Token.Null;
- }
- break;
-
- }
-
- throw new Exception("Could not find token at index " + --index);
- }
-}
-#endregion
-
diff --git a/src/Handlers/ContextMenuHandler.cs b/src/Handlers/ContextMenuHandler.cs
index ee860c2..641a7b7 100644
--- a/src/Handlers/ContextMenuHandler.cs
+++ b/src/Handlers/ContextMenuHandler.cs
@@ -1,121 +1,234 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using CefSharp;
-using System.Windows.Forms;
-using CefSharp.WinForms;
-
-namespace SharpBrowser {
- internal class ContextMenuHandler : IContextMenuHandler {
-
- private const int ShowDevTools = 26501;
- private const int CloseDevTools = 26502;
- private const int SaveImageAs = 26503;
- private const int SaveAsPdf = 26504;
- private const int SaveLinkAs = 26505;
- private const int CopyLinkAddress = 26506;
- private const int OpenLinkInNewTab = 26507;
- private const int CloseTab = 40007;
- private const int RefreshTab = 40008;
- MainForm myForm;
-
- private string lastSelText = "";
-
- public ContextMenuHandler(MainForm form) {
- myForm = form;
- }
-
- public void OnBeforeContextMenu(IWebBrowser browserControl, IBrowser browser, IFrame frame, IContextMenuParams parameters, IMenuModel model) {
-
- // clear the menu
- model.Clear();
-
- // save text
- lastSelText = parameters.SelectionText;
-
- // to copy text
- if (parameters.SelectionText.CheckIfValid()) {
- model.AddItem(CefMenuCommand.Copy, "Copy");
- model.AddSeparator();
- }
-
- //Removing existing menu item
- //bool removed = model.Remove(CefMenuCommand.ViewSource); // Remove "View Source" option
- if (parameters.LinkUrl != "") {
- model.AddItem((CefMenuCommand)OpenLinkInNewTab, "Open link in new tab");
- model.AddItem((CefMenuCommand)CopyLinkAddress, "Copy link");
- model.AddSeparator();
- }
-
- if (parameters.HasImageContents && parameters.SourceUrl.CheckIfValid()) {
-
- // RIGHT CLICKED ON IMAGE
-
- }
-
- if (parameters.SelectionText != null) {
-
- // TEXT IS SELECTED
-
- }
-
- //Add new custom menu items
- //#if DEBUG
- model.AddItem((CefMenuCommand)ShowDevTools, "Developer tools");
- model.AddItem(CefMenuCommand.ViewSource, "View source");
- model.AddSeparator();
- //#endif
-
- model.AddItem((CefMenuCommand)RefreshTab, "Refresh tab");
- model.AddItem((CefMenuCommand)CloseTab, "Close tab");
-
- }
-
- public bool OnContextMenuCommand(IWebBrowser browserControl, IBrowser browser, IFrame frame, IContextMenuParams parameters, CefMenuCommand commandId, CefEventFlags eventFlags) {
-
- int id = (int)commandId;
-
- if (id == ShowDevTools) {
- browser.ShowDevTools();
- }
- if (id == CloseDevTools) {
- browser.CloseDevTools();
- }
- if (id == SaveImageAs) {
- browser.GetHost().StartDownload(parameters.SourceUrl);
- }
- if (id == SaveLinkAs) {
- browser.GetHost().StartDownload(parameters.LinkUrl);
- }
- if (id == OpenLinkInNewTab) {
- ChromiumWebBrowser newBrowser = myForm.AddNewBrowserTab(parameters.LinkUrl, false, browser.MainFrame.Url);
- }
- if (id == CopyLinkAddress) {
- Clipboard.SetText(parameters.LinkUrl);
- }
- if (id == CloseTab) {
- myForm.InvokeOnParent(delegate () {
- myForm.CloseActiveTab();
- });
- }
- if (id == RefreshTab) {
- myForm.InvokeOnParent(delegate () {
- myForm.RefreshActiveTab();
- });
- }
-
- return false;
- }
-
- public void OnContextMenuDismissed(IWebBrowser browserControl, IBrowser browser, IFrame frame) {
-
- }
-
- public bool RunContextMenu(IWebBrowser browserControl, IBrowser browser, IFrame frame, IContextMenuParams parameters, IMenuModel model, IRunContextMenuCallback callback) {
-
- // show default menu
- return false;
- }
- }
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using CefSharp;
+using System.Windows.Forms;
+using CefSharp.WinForms;
+
+namespace SharpBrowser.Handlers {
+ internal class ContextMenuHandler : IContextMenuHandler {
+
+ private const int ShowDevTools = 26501;
+ private const int CloseDevTools = 26502;
+ private const int SaveImageAs = 26503;
+ private const int SaveAsPdf = 26504;
+ private const int SaveLinkAs = 26505;
+ private const int CopyLinkAddress = 26506;
+ private const int OpenLinkInNewTab = 26507;
+ private const int CloseTab = 40007;
+ private const int RefreshTab = 40008;
+ private const int Print = 26508;
+ readonly MainForm myForm;
+
+ private string lastSelText = "";
+
+ public ContextMenuHandler(MainForm form) {
+ myForm = form;
+ }
+
+ //
+ // Summary:
+ // Called before a context menu is displayed. The model can be cleared to show no
+ // context menu or modified to show a custom menu.
+ //
+ // Parameters:
+ // chromiumWebBrowser:
+ // the ChromiumWebBrowser control
+ //
+ // browser:
+ // the browser object
+ //
+ // frame:
+ // The frame the request is coming from
+ //
+ // parameters:
+ // provides information about the context menu state
+ //
+ // model:
+ // initially contains the default context menu
+ public void OnBeforeContextMenu(IWebBrowser browserControl, IBrowser browser, IFrame frame, IContextMenuParams parameters, IMenuModel model) {
+
+ // clear the menu
+ model.Clear();
+
+ // save text
+ lastSelText = parameters.SelectionText;
+
+ // to copy text
+ if (parameters.SelectionText.CheckIfValid()) {
+ model.AddItem(CefMenuCommand.Copy, "Copy");
+ model.AddSeparator();
+ }
+
+ //Removing existing menu item
+ //bool removed = model.Remove(CefMenuCommand.ViewSource); // Remove "View Source" option
+ if (parameters.LinkUrl != "") {
+ model.AddItem((CefMenuCommand)OpenLinkInNewTab, "Open link in new tab");
+ model.AddItem((CefMenuCommand)CopyLinkAddress, "Copy link");
+ model.AddSeparator();
+ }
+
+ if (parameters.HasImageContents && parameters.SourceUrl.CheckIfValid()) {
+
+ // RIGHT CLICKED ON IMAGE
+
+ }
+
+ if (parameters.SelectionText != null) {
+
+ // TEXT IS SELECTED
+
+ }
+
+ //Add new custom menu items
+ //#if DEBUG
+ model.AddItem((CefMenuCommand)ShowDevTools, "Developer tools");
+ model.AddItem(CefMenuCommand.ViewSource, "View source");
+ model.AddSeparator();
+ //#endif
+
+ model.AddItem((CefMenuCommand)RefreshTab, "Refresh tab");
+ model.AddItem((CefMenuCommand)CloseTab, "Close tab");
+ model.AddSeparator();
+
+ model.AddItem((CefMenuCommand)SaveAsPdf, "Save as PDF");
+ model.AddItem((CefMenuCommand)Print, "Print Page");
+
+ }
+
+ //
+ // Summary:
+ // Called to execute a command selected from the context menu. See cef_menu_id_t
+ // for the command ids that have default implementations. All user-defined command
+ // ids should be between MENU_ID_USER_FIRST and MENU_ID_USER_LAST.
+ //
+ // Parameters:
+ // chromiumWebBrowser:
+ // the ChromiumWebBrowser control
+ //
+ // browser:
+ // the browser object
+ //
+ // frame:
+ // The frame the request is coming from
+ //
+ // parameters:
+ // will have the same values as what was passed to
+ //
+ // commandId:
+ // menu command id
+ //
+ // eventFlags:
+ // event flags
+ //
+ // Returns:
+ // Return true if the command was handled or false for the default implementation.
+ public bool OnContextMenuCommand(IWebBrowser browserControl, IBrowser browser, IFrame frame, IContextMenuParams parameters, CefMenuCommand commandId, CefEventFlags eventFlags) {
+
+ int id = (int)commandId;
+
+ if (id == ShowDevTools) {
+ browser.ShowDevTools();
+ }
+ if (id == CloseDevTools) {
+ browser.CloseDevTools();
+ }
+ if (id == SaveImageAs) {
+ browser.GetHost().StartDownload(parameters.SourceUrl);
+ }
+ if (id == SaveLinkAs) {
+ browser.GetHost().StartDownload(parameters.LinkUrl);
+ }
+ if (id == OpenLinkInNewTab) {
+ ChromiumWebBrowser newBrowser = myForm.AddNewBrowserTab(parameters.LinkUrl, false, browser.MainFrame.Url);
+ }
+ if (id == CopyLinkAddress) {
+ Clipboard.SetText(parameters.LinkUrl);
+ }
+ if (id == CloseTab) {
+ myForm.InvokeOnParent(delegate () {
+ myForm.CloseActiveTab();
+ });
+ }
+ if (id == RefreshTab) {
+ myForm.InvokeOnParent(delegate () {
+ myForm.RefreshActiveTab();
+ });
+ }
+ if (id == SaveAsPdf) {
+ SaveAsPDF(browser);
+ }
+ if (id == Print)
+ {
+ browser.Print();
+ }
+
+ return false;
+ }
+
+ public static void SaveAsPDF(IBrowser browser) {
+ SaveFileDialog sfd = new SaveFileDialog();
+ sfd.Filter = "PDF Files|*.pdf";
+ //sfd.DefaultExt = (browser.MainFrame.Name ?? "Document") + ".pdf";
+ if (sfd.ShowDialog() == DialogResult.OK) {
+ browser.PrintToPdfAsync(sfd.FileName, new PdfPrintSettings() {
+ PrintBackground = true,
+ });
+ }
+ }
+
+ //
+ // Summary:
+ // Called when the context menu is dismissed irregardless of whether the menu was
+ // empty or a command was selected.
+ //
+ // Parameters:
+ // chromiumWebBrowser:
+ // the ChromiumWebBrowser control
+ //
+ // browser:
+ // the browser object
+ //
+ // frame:
+ // The frame the request is coming from
+ public void OnContextMenuDismissed(IWebBrowser browserControl, IBrowser browser, IFrame frame) {
+
+ }
+
+ //
+ // Summary:
+ // Called to allow custom display of the context menu. For custom display return
+ // true and execute callback either synchronously or asynchronously with the selected
+ // command Id. For default display return false. Do not keep references to parameters
+ // or model outside of this callback.
+ //
+ // Parameters:
+ // chromiumWebBrowser:
+ // the ChromiumWebBrowser control
+ //
+ // browser:
+ // the browser object
+ //
+ // frame:
+ // The frame the request is coming from
+ //
+ // parameters:
+ // provides information about the context menu state
+ //
+ // model:
+ // contains the context menu model resulting from OnBeforeContextMenu
+ //
+ // callback:
+ // the callback to execute for custom display
+ //
+ // Returns:
+ // For custom display return true and execute callback either synchronously or asynchronously
+ // with the selected command ID.
+ public bool RunContextMenu(IWebBrowser browserControl, IBrowser browser, IFrame frame, IContextMenuParams parameters, IMenuModel model, IRunContextMenuCallback callback) {
+
+ // show default menu
+ return false;
+ }
+ }
}
\ No newline at end of file
diff --git a/src/Handlers/DownloadHandler.cs b/src/Handlers/DownloadHandler.cs
index 74ca027..fb8e294 100644
--- a/src/Handlers/DownloadHandler.cs
+++ b/src/Handlers/DownloadHandler.cs
@@ -1,48 +1,110 @@
using CefSharp;
+using SharpBrowser.Managers;
-namespace SharpBrowser {
+namespace SharpBrowser.Handlers {
internal class DownloadHandler : IDownloadHandler {
- MainForm myForm;
+ readonly MainForm myForm;
public DownloadHandler(MainForm form) {
myForm = form;
}
- public void OnBeforeDownload(IWebBrowser webBrowser, IBrowser browser, DownloadItem item, IBeforeDownloadCallback callback) {
+ //
+ // Summary:
+ // Called before a download begins in response to a user-initiated action (e.g.
+ // alt + link click or link click that returns a `Content-Disposition: attachment`
+ // response from the server).
+ //
+ // Parameters:
+ // chromiumWebBrowser:
+ // the ChromiumWebBrowser control
+ //
+ // browser:
+ // The browser instance
+ //
+ // url:
+ // is the target download URL
+ //
+ // requestMethod:
+ // is the target method (GET, POST, etc)
+ //
+ // Returns:
+ // Return true to proceed with the download or false to cancel the download.
+ public bool CanDownload(IWebBrowser chromiumWebBrowser, IBrowser browser, string url, string requestMethod) {
+ return true;
+ }
+
+ //
+ // Summary:
+ // Called before a download begins.
+ //
+ // Parameters:
+ // chromiumWebBrowser:
+ // the ChromiumWebBrowser control
+ //
+ // browser:
+ // The browser instance
+ //
+ // downloadItem:
+ // Represents the file being downloaded.
+ //
+ // callback:
+ // Callback interface used to asynchronously continue a download.
+
+ public bool OnBeforeDownload(IWebBrowser chromiumWebBrowser, IBrowser browser, DownloadItem item, IBeforeDownloadCallback callback) {
if (!callback.IsDisposed) {
using (callback) {
- myForm.UpdateDownloadItem(item);
+ DownloadManager.UpdateDownloadItem(item);
// ask browser what path it wants to save the file into
- string path = myForm.CalcDownloadPath(item);
+ string path = DownloadManager.CalcDownloadPath(item);
// if file should not be saved, path will be null, so skip file
- if (path != null) {
+ if (path == null) {
// skip file
callback.Continue(path, false);
+ return false;
- } else {
-
- // download file
- callback.Dispose();
+ }
+ else {
// open the downloads tab
- myForm.OpenDownloadsTab();
-
+ myForm.OpenDownloads();
+ callback.Continue(path, true);
+ return true;
}
}
}
+ return false;
}
+ //
+ // Summary:
+ // Called when a download's status or progress information has been updated. This
+ // may be called multiple times before and after CefSharp.IDownloadHandler.OnBeforeDownload(CefSharp.IWebBrowser,CefSharp.IBrowser,CefSharp.DownloadItem,CefSharp.IBeforeDownloadCallback).
+ //
+ // Parameters:
+ // chromiumWebBrowser:
+ // the ChromiumWebBrowser control
+ //
+ // browser:
+ // The browser instance
+ //
+ // downloadItem:
+ // Represents the file being downloaded.
+ //
+ // callback:
+ // The callback used to Cancel/Pause/Resume the process
public void OnDownloadUpdated(IWebBrowser webBrowser, IBrowser browser, DownloadItem downloadItem, IDownloadItemCallback callback) {
- myForm.UpdateDownloadItem(downloadItem);
- if (downloadItem.IsInProgress && myForm.CancelRequests.Contains(downloadItem.Id)) {
+ DownloadManager.UpdateDownloadItem(downloadItem);
+ if (downloadItem.IsInProgress && DownloadManager.CancelRequests.Contains(downloadItem.Id)) {
callback.Cancel();
}
//Console.WriteLine(downloadItem.Url + " %" + downloadItem.PercentComplete + " complete");
}
+
}
}
\ No newline at end of file
diff --git a/src/Handlers/HostHandler.cs b/src/Handlers/HostHandler.cs
index 28433bf..651ca0e 100644
--- a/src/Handlers/HostHandler.cs
+++ b/src/Handlers/HostHandler.cs
@@ -1,10 +1,7 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Windows.Forms;
+using Newtonsoft.Json;
+using SharpBrowser.Managers;
-namespace SharpBrowser {
+namespace SharpBrowser.Handlers {
///
/// functions in this class are accessible by JS using the code `host.X()`
@@ -19,19 +16,14 @@ public void addNewBrowserTab(string url, bool focusNewTab = true) {
myForm.AddNewBrowserTab(url, focusNewTab);
}
public string getDownloads() {
- lock (myForm.downloads) {
- string x = JSON.Instance.ToJSON(myForm.downloads);
- //MessageBox.Show(x);
- return x;
+ lock (DownloadManager.Downloads) {
+ var json = JsonConvert.SerializeObject(DownloadManager.Downloads.Values);
+ return json;
}
}
public bool cancelDownload(int downloadId) {
- lock (myForm.downloadCancelRequests) {
- if (!myForm.downloadCancelRequests.Contains(downloadId)) {
- myForm.downloadCancelRequests.Add(downloadId);
- }
- }
+ DownloadManager.Cancel(downloadId);
return true;
}
public void refreshActiveTab() {
diff --git a/src/Handlers/KeyboardHandler.cs b/src/Handlers/KeyboardHandler.cs
index 6b54b16..0141eca 100644
--- a/src/Handlers/KeyboardHandler.cs
+++ b/src/Handlers/KeyboardHandler.cs
@@ -1,27 +1,98 @@
- using System;
+using System;
using System.Collections.Generic;
using System.Windows.Forms;
using CefSharp;
+using SharpBrowser.Model;
-
-namespace SharpBrowser {
+namespace SharpBrowser.Handlers {
internal class KeyboardHandler : IKeyboardHandler {
MainForm myForm;
- public static List Hotkeys = new List();
+ public static List Hotkeys = new List();
public static void AddHotKey(Form form, Action function, Keys key, bool ctrl = false, bool shift = false, bool alt = false) {
- Utils.AddHotKey(form, function, key, ctrl, shift, alt);
- Hotkeys.Add(new SharpHotKey(function, key, ctrl, shift, alt));
+ WinFormsUtils.AddHotKey(form, function, key, ctrl, shift, alt);
+ Hotkeys.Add(new BrowserHotKey(function, key, ctrl, shift, alt));
}
public KeyboardHandler(MainForm form) {
myForm = form;
}
+
+ // Summary:
+ // Called before a keyboard event is sent to the renderer. Return true if the event
+ // was handled or false otherwise. If the event will be handled in CefSharp.IKeyboardHandler.OnKeyEvent(CefSharp.IWebBrowser,CefSharp.IBrowser,CefSharp.KeyType,System.Int32,System.Int32,CefSharp.CefEventFlags,System.Boolean)
+ // as a keyboard shortcut set isKeyboardShortcut to true and return false.
+ //
+ // Parameters:
+ // chromiumWebBrowser:
+ // the ChromiumWebBrowser control
+ //
+ // browser:
+ // The browser instance.
+ //
+ // type:
+ // Whether this was a key up/down/raw/etc...
+ //
+ // windowsKeyCode:
+ // The Windows key code for the key event. This value is used by the DOM specification.
+ // Sometimes it comes directly from the event (i.e. on Windows) and sometimes it's
+ // determined using a mapping function. See WebCore/platform/chromium/KeyboardCodes.h
+ // for the list of values.
+ //
+ // nativeKeyCode:
+ // The native key code. On Windows this appears to be in the format of WM_KEYDOWN/WM_KEYUP/etc...
+ // lParam data.
+ //
+ // modifiers:
+ // What other modifier keys are currently down: Shift/Control/Alt/OS X Command/etc...
+ //
+ // isSystemKey:
+ // Indicates whether the event is considered a "system key" event (see http://msdn.microsoft.com/en-us/library/ms646286(VS.85).aspx
+ // for details).
+ //
+ // isKeyboardShortcut:
+ // See the summary for an explanation of when to set this to true.
+ //
+ // Returns:
+ // Returns true if the event was handled or false otherwise.
public bool OnPreKeyEvent(IWebBrowser browserControl, IBrowser browser, KeyType type, int windowsKeyCode, int nativeKeyCode, CefEventFlags modifiers, bool isSystemKey, ref bool isKeyboardShortcut) {
return false;
}
- ///
+ //
+ // Summary:
+ // Called after the renderer and JavaScript in the page has had a chance to handle
+ // the event. Return true if the keyboard event was handled or false otherwise.
+ //
+ // Parameters:
+ // chromiumWebBrowser:
+ // the ChromiumWebBrowser control
+ //
+ // browser:
+ // The browser instance.
+ //
+ // type:
+ // Whether this was a key up/down/raw/etc...
+ //
+ // windowsKeyCode:
+ // The Windows key code for the key event. This value is used by the DOM specification.
+ // Sometimes it comes directly from the event (i.e. on Windows) and sometimes it's
+ // determined using a mapping function. See WebCore/platform/chromium/KeyboardCodes.h
+ // for the list of values.
+ //
+ // nativeKeyCode:
+ // The native key code. On Windows this appears to be in the format of WM_KEYDOWN/WM_KEYUP/etc...
+ // lParam data.
+ //
+ // modifiers:
+ // What other modifier keys are currently down: Shift/Control/Alt/OS X Command/etc...
+ //
+ // isSystemKey:
+ // Indicates whether the event is considered a "system key" event (see http://msdn.microsoft.com/en-us/library/ms646286(VS.85).aspx
+ // for details).
+ //
+ // Returns:
+ // Return true if the keyboard event was handled or false otherwise.
public bool OnKeyEvent(IWebBrowser browserControl, IBrowser browser, KeyType type, int windowsKeyCode, int nativeKeyCode, CefEventFlags modifiers, bool isSystemKey) {
if (type == KeyType.RawKeyDown) {
@@ -34,7 +105,7 @@ public bool OnKeyEvent(IWebBrowser browserControl, IBrowser browser, KeyType typ
bool altDown = mod.IsBitmaskOn((int)CefEventFlags.AltDown);
// per registered hotkey
- foreach (SharpHotKey key in Hotkeys) {
+ foreach (BrowserHotKey key in Hotkeys) {
if (key.KeyCode == windowsKeyCode) {
if (key.Ctrl == ctrlDown && key.Shift == shiftDown && key.Alt == altDown) {
myForm.InvokeOnParent(delegate () {
diff --git a/src/Handlers/LifeSpanHandler.cs b/src/Handlers/LifeSpanHandler.cs
index a24f18c..11e31c3 100644
--- a/src/Handlers/LifeSpanHandler.cs
+++ b/src/Handlers/LifeSpanHandler.cs
@@ -1,6 +1,6 @@
using CefSharp;
-namespace SharpBrowser {
+namespace SharpBrowser.Handlers {
internal class LifeSpanHandler : ILifeSpanHandler {
MainForm myForm;
diff --git a/src/Handlers/PermissionHandler.cs b/src/Handlers/PermissionHandler.cs
new file mode 100644
index 0000000..691c84d
--- /dev/null
+++ b/src/Handlers/PermissionHandler.cs
@@ -0,0 +1,101 @@
+using CefSharp;
+using SharpBrowser.Config;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace SharpBrowser.Handlers {
+ internal class PermissionHandler : IPermissionHandler {
+ ///
+ /// Called when a permission prompt handled via OnShowPermissionPrompt(IWebBrowser, IBrowser, UInt64, String, PermissionRequestType, IPermissionPromptCallback) is dismissed. result will be the value passed to Continue(PermissionRequestResult) or Ignore if the dialog was dismissed for other reasons such as navigation, browser closure, etc. This method will not be called if OnShowPermissionPrompt(IWebBrowser, IBrowser, UInt64, String, PermissionRequestType, IPermissionPromptCallback) returned false for promptId.
+ ///
+ /// Will match the value that was passed to OnShowPermissionPrompt
+ /// will be the value passed to Continue(PermissionRequestResult) or Ignore if the dialog was dismissed for other reasons such as navigation, browser closure, etc. This method will not be called if OnShowPermissionPrompt(IWebBrowser, IBrowser, UInt64, String, PermissionRequestType, IPermissionPromptCallback) returned false for promptId.
+ void IPermissionHandler.OnDismissPermissionPrompt(IWebBrowser chromiumWebBrowser, IBrowser browser, ulong promptId, PermissionRequestResult result) {
+
+ }
+
+ ///
+ /// Called when a page requests permission to access media.
+ /// With the Chrome runtime, default handling will display the permission request UI.
+ /// With the Alloy runtime, default handling will deny the request.
+ /// This method will not be called if the "--enable-media-stream" command-line switch is used to grant all permissions.
+ ///
+ /// is the URL origin requesting permission.
+ /// is a combination of values that represent the requested permissions
+ /// Callback interface used for asynchronous continuation of media access.
+ bool IPermissionHandler.OnRequestMediaAccessPermission(IWebBrowser chromiumWebBrowser, IBrowser browser, IFrame frame, string requestingOrigin, MediaAccessPermissionType requestedPermissions, IMediaAccessCallback callback) {
+ return true;
+ }
+
+ ///
+ /// Called when a page should show a permission prompt.
+ ///
+ /// Uniquely identifies the prompt.
+ /// Is the URL origin requesting permission.
+ /// Is a combination of values from PermissionRequestType that represent the requested permissions.
+ /// Callback interface used for asynchronous continuation of permission prompts.
+ bool IPermissionHandler.OnShowPermissionPrompt(IWebBrowser chromiumWebBrowser, IBrowser browser, ulong promptId, string requestingOrigin, PermissionRequestType requestedPermissions, IPermissionPromptCallback callback) {
+
+ var allow = false;
+
+
+ // DENY FEATURES THAT ARE NOT SUPPORTED
+ switch (requestedPermissions) {
+
+ case PermissionRequestType.Notifications:
+ case PermissionRequestType.TopLevelStorageAccess:
+ case PermissionRequestType.WindowManagement:
+ case PermissionRequestType.RegisterProtocolHandler:
+ allow = false;
+ break;
+
+
+
+ // ACCEPT/DENY BASED ON APP CONFIG
+
+ case PermissionRequestType.MidiSysex:
+ allow = BrowserConfig.WebMidi;
+ break;
+ case PermissionRequestType.CameraStream:
+ case PermissionRequestType.CameraPanTiltZoom:
+ allow = BrowserConfig.Camera;
+ break;
+ case PermissionRequestType.MicStream:
+ allow = BrowserConfig.Microphone;
+ break;
+ case PermissionRequestType.Clipboard:
+ allow = BrowserConfig.JavascriptClipboard;
+ break;
+ case PermissionRequestType.FileSystemAccess:
+ allow = BrowserConfig.LocalFiles;
+ break;
+ case PermissionRequestType.StorageAccess:
+ allow = BrowserConfig.LocalStorage;
+ break;
+
+
+ // ACCEPT THINGS THAT ARE SUPPORTED
+
+ case PermissionRequestType.LocalFonts:
+ case PermissionRequestType.MultipleDownloads:
+ allow = true;
+ break;
+
+ }
+
+
+ // DENY UNKNOWN BY DEFAULT
+ if (allow) {
+ callback.Continue(PermissionRequestResult.Accept);
+ }else {
+ callback.Continue(PermissionRequestResult.Deny);
+ }
+
+ // returning true means the browser has handled this request
+ return true;
+ }
+ }
+}
diff --git a/src/Handlers/RequestHandler.cs b/src/Handlers/RequestHandler.cs
index cb2a5e6..2db90d7 100644
--- a/src/Handlers/RequestHandler.cs
+++ b/src/Handlers/RequestHandler.cs
@@ -1,66 +1,61 @@
-using System.Collections.Specialized;
+using System;
+using System.Collections.Specialized;
using System.Security.Cryptography.X509Certificates;
+using System.Windows.Forms;
using CefSharp;
-namespace SharpBrowser {
+namespace SharpBrowser.Handlers {
internal class RequestHandler : IRequestHandler {
MainForm myForm;
+ public static bool settings__onCtrlClick_focusNewTab = true;
+
public RequestHandler(MainForm form) {
myForm = form;
}
- public bool CanGetCookies(IWebBrowser chromiumWebBrowser, IBrowser browser, IFrame frame, IRequest request) {
-
- return true;
- }
-
- public bool CanSetCookie(IWebBrowser chromiumWebBrowser, IBrowser browser, IFrame frame, IRequest request, Cookie cookie) {
-
- return true;
- }
+ //
// Summary:
// Called when the browser needs credentials from the user.
//
// Parameters:
- // frame:
- // The frame object that needs credentials (This will contain the URL that is
- // being requested.)
+ // chromiumWebBrowser:
+ // The ChromiumWebBrowser control
+ //
+ // browser:
+ // the browser object
+ //
+ // originUrl:
+ // is the origin making this authentication request
//
// isProxy:
// indicates whether the host is a proxy server
//
- // callback:
- // Callback interface used for asynchronous continuation of authentication requests.
- //
- // Returns:
- // Return true to continue the request and call CefAuthCallback::Continue()
- // when the authentication information is available. Return false to cancel
- // the request.
- public bool GetAuthCredentials(IWebBrowser browserControl, IBrowser browser, IFrame frame, bool isProxy, string host, int port, string realm, string scheme, IAuthCallback callback) {
-
- return true;
- }
+ // host:
+ // hostname
//
- // Summary:
- // Called on the CEF IO thread to optionally filter resource response content.
+ // port:
+ // port number
//
- // Parameters:
- // frame:
- // The frame that is being redirected.
+ // realm:
+ // realm
//
- // request:
- // the request object - cannot be modified in this callback
+ // scheme:
+ // scheme
//
- // response:
- // the response object - cannot be modified in this callback
+ // callback:
+ // Callback interface used for asynchronous continuation of authentication requests.
//
// Returns:
- // Return an IResponseFilter to intercept this response, otherwise return null
- public IResponseFilter GetResourceResponseFilter(IWebBrowser browserControl, IBrowser browser, IFrame frame, IRequest request, IResponse response) {
- return null;
+ // Return true to continue the request and call CefSharp.IAuthCallback.Continue(System.String,System.String)
+ // when the authentication information is available. Return false to cancel the
+ // request.
+ public bool GetAuthCredentials(IWebBrowser chromiumWebBrowser, IBrowser browser, string originUrl, bool isProxy, string host, int port, string realm, string scheme, IAuthCallback callback) {
+ // Return false to cancel the request.
+ return false;
}
+
//
// Summary:
// Called before browser navigation. If the navigation is allowed CefSharp.IWebBrowser.FrameLoadStart
@@ -84,39 +79,8 @@ public IResponseFilter GetResourceResponseFilter(IWebBrowser browserControl, IBr
public bool OnBeforeBrowse(IWebBrowser chromiumWebBrowser, IBrowser browser, IFrame frame, IRequest request, bool userGesture, bool isRedirect) {
return false;
}
+
- //
- // Summary:
- // Called before a resource request is loaded. For async processing return CefSharp.CefReturnValue.ContinueAsync
- // and execute CefSharp.IRequestCallback.Continue(System.Boolean) or CefSharp.IRequestCallback.Cancel()
- //
- // Parameters:
- // frame:
- // The frame object
- //
- // request:
- // the request object - can be modified in this callback.
- //
- // callback:
- // Callback interface used for asynchronous continuation of url requests.
- //
- // Returns:
- // To cancel loading of the resource return CefSharp.CefReturnValue.Cancel or
- // CefSharp.CefReturnValue.Continue to allow the resource to load normally.
- // For async return CefSharp.CefReturnValue.ContinueAsync
- public CefReturnValue OnBeforeResourceLoad(IWebBrowser browserControl, IBrowser browser, IFrame frame, IRequest request, IRequestCallback callback) {
-
- // if referer given
- var tab = myForm.GetTabByBrowser(browserControl);
- if (tab != null && tab.RefererURL != null) {
-
- // Set referer
- request.SetReferrer(tab.RefererURL, ReferrerPolicy.Always);
-
- }
-
- return CefSharp.CefReturnValue.Continue;
- }
//
// Summary:
// Called to handle requests for URLs with an invalid SSL certificate. Return
@@ -145,6 +109,8 @@ public CefReturnValue OnBeforeResourceLoad(IWebBrowser browserControl, IBrowser
public bool OnCertificateError(IWebBrowser browserControl, IBrowser browser, CefErrorCode errorCode, string requestUrl, ISslInfo sslInfo, IRequestCallback callback) {
return true;
}
+
+
//
// Summary:
// Called on the UI thread before OnBeforeBrowse in certain limited cases where
@@ -170,8 +136,36 @@ public bool OnCertificateError(IWebBrowser browserControl, IBrowser browser, Cef
// Returns:
// Return true to cancel the navigation or false to allow the navigation to
// proceed in the source browser's top-level frame.
- public bool OnOpenUrlFromTab(IWebBrowser browserControl, IBrowser browser, IFrame frame, string targetUrl, WindowOpenDisposition targetDisposition, bool userGesture) {
+ public bool OnOpenUrlFromTab(IWebBrowser browserControl, IBrowser browser, IFrame frame,
+ string targetUrl, WindowOpenDisposition targetDisposition, bool userGesture) {
+ //return false;
+
+ // check if the user intended to open the link in a new tab
+ // (Ctrl+Click often results in NewBackgroundTab or NewForegroundTab)
+ if (targetDisposition == WindowOpenDisposition.NewForegroundTab ||
+ targetDisposition == WindowOpenDisposition.NewBackgroundTab)
+ {
+ // Check if it was a user gesture (actual click)
+ if (userGesture)
+ {
+ myForm.Invoke((MethodInvoker)(() => {
+ myForm.AddNewBrowserTab(targetUrl,
+ //focusNewTab: (targetDisposition == WindowOpenDisposition.NewForegroundTab),
+ focusNewTab: settings__onCtrlClick_focusNewTab,
+ browser.MainFrame.Url
+ );
+ }));
+
+
+ //handled.. (dont load it in the current tab)
+ return true;
+ }
+ }
+
+ // For all other cases, return false to let the default navigation proceed.
return false;
+
+
}
//
// Summary:
@@ -182,22 +176,7 @@ public bool OnOpenUrlFromTab(IWebBrowser browserControl, IBrowser browser, IFram
// path of the plugin that crashed
public void OnPluginCrashed(IWebBrowser browserControl, IBrowser browser, string pluginPath) {
}
- //
- // Summary:
- // Called on the UI thread to handle requests for URLs with an unknown protocol
- // component. SECURITY WARNING: YOU SHOULD USE THIS METHOD TO ENFORCE RESTRICTIONS
- // BASED ON SCHEME, HOST OR OTHER URL ANALYSIS BEFORE ALLOWING OS EXECUTION.
- //
- // Parameters:
- // url:
- // the request url
- //
- // Returns:
- // return to true to attempt execution via the registered OS protocol handler,
- // if any. Otherwise return false.
- public bool OnProtocolExecution(IWebBrowser browserControl, IBrowser browser, string url) {
- return true;
- }
+
//
// Summary:
// Called when JavaScript requests a specific storage quota size via the webkitStorageInfo.requestQuota
@@ -230,7 +209,8 @@ public bool OnQuotaRequest(IWebBrowser browserControl, IBrowser browser, string
// Parameters:
// status:
// indicates how the process terminated.
- public void OnRenderProcessTerminated(IWebBrowser browserControl, IBrowser browser, CefTerminationStatus status) {
+ public void OnRenderProcessTerminated(IWebBrowser chromiumWebBrowser, IBrowser browser, CefTerminationStatus status, int errorCode, string errorMessage) {
+
}
//
// Summary:
@@ -238,116 +218,101 @@ public void OnRenderProcessTerminated(IWebBrowser browserControl, IBrowser brows
// is ready to receive/handle IPC messages in the render process.
public void OnRenderViewReady(IWebBrowser browserControl, IBrowser browser) {
}
+
//
// Summary:
- // Called on the CEF IO thread when a resource load has completed.
+ // Called on the CEF IO thread before a resource request is initiated.
//
// Parameters:
+ // chromiumWebBrowser:
+ // the ChromiumWebBrowser control
+ //
+ // browser:
+ // represent the source browser of the request
+ //
// frame:
- // The frame that is being redirected.
+ // represent the source frame of the request
//
// request:
- // the request object - cannot be modified in this callback
+ // represents the request contents and cannot be modified in this callback
//
- // response:
- // the response object - cannot be modified in this callback
+ // isNavigation:
+ // will be true if the resource request is a navigation
//
- // status:
- // indicates the load completion status
+ // isDownload:
+ // will be true if the resource request is a download
+ //
+ // requestInitiator:
+ // is the origin (scheme + domain) of the page that initiated the request
+ //
+ // disableDefaultHandling:
+ // to true to disable default handling of the request, in which case it will need
+ // to be handled via CefSharp.IResourceRequestHandler.GetResourceHandler(CefSharp.IWebBrowser,CefSharp.IBrowser,CefSharp.IFrame,CefSharp.IRequest)
+ // or it will be canceled
//
- // receivedContentLength:
- // is the number of response bytes actually read.
- public void OnResourceLoadComplete(IWebBrowser browserControl, IBrowser browser, IFrame frame, IRequest request, IResponse response, UrlRequestStatus status, long receivedContentLength) {
+ // Returns:
+ // To allow the resource load to proceed with default handling return null. To specify
+ // a handler for the resource return a CefSharp.IResourceRequestHandler object.
+ // If this callback returns null the same method will be called on the associated
+ // CefSharp.IRequestContextHandler, if any
+ public IResourceRequestHandler GetResourceRequestHandler(IWebBrowser chromiumWebBrowser, IBrowser browser, IFrame frame, IRequest request, bool isNavigation, bool isDownload, string requestInitiator, ref bool disableDefaultHandling) {
+ var rh = new ResourceRequestHandler(myForm);
+ return rh;
}
+
+
//
// Summary:
- // Called on the IO thread when a resource load is redirected. The CefSharp.IRequest.Url
- // parameter will contain the old URL and other request-related information.
+ // Called when the browser needs user to select Client Certificate for authentication
+ // requests (eg. PKI authentication).
//
// Parameters:
- // frame:
- // The frame that is being redirected.
+ // chromiumWebBrowser:
+ // The ChromiumWebBrowser control
//
- // request:
- // the request object - cannot be modified in this callback
+ // browser:
+ // the browser object
//
- // newUrl:
- // the new URL and can be changed if desired
- public void OnResourceRedirect(IWebBrowser chromiumWebBrowser, IBrowser browser, IFrame frame, IRequest request, IResponse response, ref string newUrl) {
-
- }
-
+ // isProxy:
+ // indicates whether the host is a proxy server
//
- // Summary:
- // Called on the CEF IO thread when a resource response is received. To allow
- // the resource to load normally return false. To redirect or retry the resource
- // modify request (url, headers or post body) and return true. The response
- // object cannot be modified in this callback.
+ // host:
+ // hostname
//
- // Parameters:
- // frame:
- // The frame that is being redirected.
+ // port:
+ // port number
//
- // request:
- // the request object
+ // certificates:
+ // List of Client certificates for selection
//
- // response:
- // the response object - cannot be modified in this callback
+ // callback:
+ // Callback interface used for asynchronous continuation of client certificate selection
+ // for authentication requests.
//
// Returns:
- // To allow the resource to load normally return false. To redirect or retry
- // the resource modify request (url, headers or post body) and return true.
- public bool OnResourceResponse(IWebBrowser browserControl, IBrowser browser, IFrame frame, IRequest request, IResponse response) {
-
-
- int code = response.StatusCode;
-
-
- // if NOT FOUND
- if (code == 404) {
-
- if (!request.Url.IsURLLocalhost()) {
-
- // redirect to web archive to try and find older version
- request.Url = "http://web.archive.org/web/*/" + request.Url;
-
- } else {
-
- // show offline "file not found" page
- request.Url = MainForm.FileNotFoundURL + "?path=" + request.Url.EncodeURL();
- }
-
- return true;
- }
-
-
- // if FILE NOT FOUND
- if (code == 0 && request.Url.IsURLOfflineFile()) {
- string path = request.Url.FileURLToPath();
- if (path.FileNotExists()) {
-
- // show offline "file not found" page
- request.Url = MainForm.FileNotFoundURL + "?path=" + path.EncodeURL();
- return true;
-
- }
- } else {
-
- // if CANNOT CONNECT
- if (code == 0 || code == 444 || (code >= 500 && code <= 599)) {
+ // Return true to continue the request and call ISelectClientCertificateCallback.Select()
+ // with the selected certificate for authentication. Return false to use the default
+ // behavior where the browser selects the first certificate from the list.
+ public bool OnSelectClientCertificate(IWebBrowser chromiumWebBrowser, IBrowser browser, bool isProxy, string host, int port, X509Certificate2Collection certificates, ISelectClientCertificateCallback callback) {
+ return false;
+ }
- // show offline "cannot connect to server" page
- request.Url = MainForm.CannotConnectURL;
- return true;
- }
- }
+ //
+ // Summary:
+ // Called on the CEF UI thread when the window.document object of the main frame
+ // has been created.
+ //
+ // Parameters:
+ // chromiumWebBrowser:
+ // the ChromiumWebBrowser control
+ //
+ // browser:
+ // the browser object
+ public void OnDocumentAvailableInMainFrame(IWebBrowser chromiumWebBrowser, IBrowser browser) {
- return false;
}
- public bool OnSelectClientCertificate(IWebBrowser chromiumWebBrowser, IBrowser browser, bool isProxy, string host, int port, X509Certificate2Collection certificates, ISelectClientCertificateCallback callback) {
- return false;
- }
+
}
}
\ No newline at end of file
diff --git a/src/Handlers/ResourceRequestHandler.cs b/src/Handlers/ResourceRequestHandler.cs
new file mode 100644
index 0000000..bccf247
--- /dev/null
+++ b/src/Handlers/ResourceRequestHandler.cs
@@ -0,0 +1,313 @@
+
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Net;
+using System.Threading.Tasks;
+using CefSharp;
+using System.Windows.Forms;
+using System.Drawing;
+using CefSharp.Callback;
+using SharpBrowser.Config;
+using SharpBrowser.Utils;
+
+namespace SharpBrowser.Handlers {
+ internal class ResourceRequestHandler : IResourceRequestHandler {
+ readonly MainForm myForm;
+ public ResourceRequestHandler(MainForm form) {
+ myForm = form;
+ }
+ public void Dispose() {
+
+ }
+
+ //
+ // Summary:
+ // Called on the CEF IO thread before a resource request is loaded. .
+ //
+ // Parameters:
+ // chromiumWebBrowser:
+ // The ChromiumWebBrowser control
+ //
+ // browser:
+ // the browser object - may be null if originating from ServiceWorker or CefURLRequest
+ //
+ // frame:
+ // the frame object - may be null if originating from ServiceWorker or CefURLRequest
+ //
+ // request:
+ // the request object - can be modified in this callback.
+ //
+ // Returns:
+ // To optionally filter cookies for the request return a ICookieAccessFilter instance
+ // otherwise return null.
+ public ICookieAccessFilter GetCookieAccessFilter(IWebBrowser chromiumWebBrowser, IBrowser browser, IFrame frame, IRequest request) {
+ return null;
+ }
+ //
+ // Summary:
+ // Called on the CEF IO thread before a resource is loaded. To specify a handler
+ // for the resource return a CefSharp.IResourceHandler object
+ //
+ // Parameters:
+ // chromiumWebBrowser:
+ // The browser UI control
+ //
+ // browser:
+ // the browser object - may be null if originating from ServiceWorker or CefURLRequest
+ //
+ // frame:
+ // the frame object - may be null if originating from ServiceWorker or CefURLRequest
+ //
+ // request:
+ // the request object - cannot be modified in this callback
+ //
+ // Returns:
+ // To allow the resource to load using the default network loader return null otherwise
+ // return an instance of CefSharp.IResourceHandler with a valid stream
+ public IResourceHandler GetResourceHandler(IWebBrowser chromiumWebBrowser, IBrowser browser, IFrame frame, IRequest request) {
+
+ // allow the resource to load using the default network loader
+ return null;
+ }
+ //
+ // Summary:
+ // Called on the CEF IO thread to optionally filter resource response content.
+ //
+ // Parameters:
+ // chromiumWebBrowser:
+ // The ChromiumWebBrowser control
+ //
+ // browser:
+ // the browser object - may be null if originating from ServiceWorker or CefURLRequest
+ //
+ // frame:
+ // the frame object - may be null if originating from ServiceWorker or CefURLRequest
+ //
+ // request:
+ // the request object - cannot be modified in this callback
+ //
+ // response:
+ // the response object - cannot be modified in this callback
+ //
+ // Returns:
+ // Return an IResponseFilter to intercept this response, otherwise return null
+ public IResponseFilter GetResourceResponseFilter(IWebBrowser chromiumWebBrowser, IBrowser browser, IFrame frame, IRequest request, IResponse response) {
+ return null;
+ }
+ //
+ // Summary:
+ // Called on the CEF IO thread before a resource request is loaded. To redirect
+ // or change the resource load optionally modify request. Modification of the request
+ // URL will be treated as a redirect
+ //
+ // Parameters:
+ // chromiumWebBrowser:
+ // The ChromiumWebBrowser control
+ //
+ // browser:
+ // the browser object - may be null if originating from ServiceWorker or CefURLRequest
+ //
+ // frame:
+ // the frame object - may be null if originating from ServiceWorker or CefURLRequest
+ //
+ // request:
+ // the request object - can be modified in this callback.
+ //
+ // callback:
+ // Callback interface used for asynchronous continuation of url requests.
+ //
+ // Returns:
+ // Return CefSharp.CefReturnValue.Continue to continue the request immediately.
+ // Return CefSharp.CefReturnValue.ContinueAsync and call CefSharp.IRequestCallback.Continue(System.Boolean)
+ // or CefSharp.IRequestCallback.Cancel at a later time to continue or the cancel
+ // the request asynchronously. Return CefSharp.CefReturnValue.Cancel to cancel the
+ // request immediately.
+ public CefReturnValue OnBeforeResourceLoad(IWebBrowser chromiumWebBrowser, IBrowser browser, IFrame frame, IRequest request, IRequestCallback callback) {
+
+ // if referer given
+ var tab = myForm.GetTabByBrowser(chromiumWebBrowser);
+ if (tab != null && tab.RefererURL != null) {
+
+ // Set referer
+ request.SetReferrer(tab.RefererURL, ReferrerPolicy.Default);
+
+ }
+
+ return CefSharp.CefReturnValue.Continue;
+ }
+ //
+ // Summary:
+ // Called on the CEF UI thread to handle requests for URLs with an unknown protocol
+ // component. SECURITY WARNING: YOU SHOULD USE THIS METHOD TO ENFORCE RESTRICTIONS
+ // BASED ON SCHEME, HOST OR OTHER URL ANALYSIS BEFORE ALLOWING OS EXECUTION.
+ //
+ // Parameters:
+ // chromiumWebBrowser:
+ // The ChromiumWebBrowser control
+ //
+ // browser:
+ // the browser object - may be null if originating from ServiceWorker or CefURLRequest
+ //
+ // frame:
+ // the frame object - may be null if originating from ServiceWorker or CefURLRequest
+ //
+ // request:
+ // the request object - cannot be modified in this callback
+ //
+ // Returns:
+ // return to true to attempt execution via the registered OS protocol handler, if
+ // any. Otherwise return false.
+ public bool OnProtocolExecution(IWebBrowser chromiumWebBrowser, IBrowser browser, IFrame frame, IRequest request) {
+ return true;
+ }
+ //
+ // Summary:
+ // Called on the CEF IO thread when a resource load has completed. This method will
+ // be called for all requests, including requests that are aborted due to CEF shutdown
+ // or destruction of the associated browser. In cases where the associated browser
+ // is destroyed this callback may arrive after the CefSharp.ILifeSpanHandler.OnBeforeClose(CefSharp.IWebBrowser,CefSharp.IBrowser)
+ // callback for that browser. The CefSharp.IFrame.IsValid method can be used to
+ // test for this situation, and care should be taken not to call browser or frame
+ // methods that modify state (like LoadURL, SendProcessMessage, etc.) if the frame
+ // is invalid.
+ //
+ // Parameters:
+ // chromiumWebBrowser:
+ // The ChromiumWebBrowser control
+ //
+ // browser:
+ // the browser object - may be null if originating from ServiceWorker or CefURLRequest
+ //
+ // frame:
+ // the frame object - may be null if originating from ServiceWorker or CefURLRequest
+ //
+ // request:
+ // the request object - cannot be modified in this callback
+ //
+ // response:
+ // the response object - cannot be modified in this callback
+ //
+ // status:
+ // indicates the load completion status
+ //
+ // receivedContentLength:
+ // is the number of response bytes actually read.
+ public void OnResourceLoadComplete(IWebBrowser chromiumWebBrowser, IBrowser browser, IFrame frame, IRequest request, IResponse response, UrlRequestStatus status, long receivedContentLength) {
+
+ int code = response.StatusCode;
+
+
+ // exit if frame is invalid (if the frame has closed, for example)
+ if (!frame.IsValid) {
+ return;
+ }
+
+
+ // if NOT FOUND
+ if (code == 404) {
+
+ if (!request.Url.IsURLLocalhost()) {
+
+ // redirect to web archive to try and find older version
+ frame.LoadUrl("http://web.archive.org/web/*/" + request.Url);
+
+ }
+ else {
+
+ // show offline "file not found" page
+ frame.LoadUrl(BrowserConfig.FileNotFoundURL + "?path=" + request.Url.EncodeURL());
+ }
+
+ }
+
+
+ // if FILE NOT FOUND
+ else if (request.Url.IsURLOfflineFile()) {
+ string path = request.Url.FileURLToPath();
+ if (path.FileNotExists()) {
+
+ // show offline "file not found" page
+ frame.LoadUrl(BrowserConfig.FileNotFoundURL + "?path=" + path.EncodeURL());
+
+ }
+ }
+ else {
+
+
+ // if CANNOT CONNECT
+ if (code == 444 || (code >= 500 && code <= 599)) {
+
+ // show offline "cannot connect to server" page
+ frame.LoadUrl(BrowserConfig.CannotConnectURL);
+ }
+
+ }
+
+ }
+ //
+ // Summary:
+ // Called on the CEF IO thread when a resource load is redirected. The request parameter
+ // will contain the old URL and other request-related information. The response
+ // parameter will contain the response that resulted in the redirect. The newUrl
+ // parameter will contain the new URL and can be changed if desired.
+ //
+ // Parameters:
+ // chromiumWebBrowser:
+ // The ChromiumWebBrowser control
+ //
+ // browser:
+ // the browser object - may be null if originating from ServiceWorker or CefURLRequest
+ //
+ // frame:
+ // the frame object - may be null if originating from ServiceWorker or CefURLRequest
+ //
+ // request:
+ // the request object - cannot be modified in this callback
+ //
+ // response:
+ // the response object - cannot be modified in this callback
+ //
+ // newUrl:
+ // the new URL and can be changed if desired
+ public void OnResourceRedirect(IWebBrowser chromiumWebBrowser, IBrowser browser, IFrame frame, IRequest request, IResponse response, ref string newUrl) {
+ }
+ //
+ // Summary:
+ // Called on the CEF IO thread when a resource response is received. To allow the
+ // resource load to proceed without modification return false. To redirect or retry
+ // the resource load optionally modify request and return true. Modification of
+ // the request URL will be treated as a redirect. Requests handled using the default
+ // network loader cannot be redirected in this callback. WARNING: Redirecting using
+ // this method is deprecated. Use OnBeforeResourceLoad or GetResourceHandler to
+ // perform redirects.
+ //
+ // Parameters:
+ // chromiumWebBrowser:
+ // The ChromiumWebBrowser control
+ //
+ // browser:
+ // the browser object - may be null if originating from ServiceWorker or CefURLRequest
+ //
+ // frame:
+ // the frame object - may be null if originating from ServiceWorker or CefURLRequest
+ //
+ // request:
+ // the request object
+ //
+ // response:
+ // the response object - cannot be modified in this callback
+ //
+ // Returns:
+ // To allow the resource load to proceed without modification return false. To redirect
+ // or retry the resource load optionally modify request and return true. Modification
+ // of the request URL will be treated as a redirect. Requests handled using the
+ // default network loader cannot be redirected in this callback.
+ public bool OnResourceResponse(IWebBrowser chromiumWebBrowser, IBrowser browser, IFrame frame, IRequest request, IResponse response) {
+
+ return false;
+
+ }
+
+ }
+}
diff --git a/src/Handlers/SchemeHandler.cs b/src/Handlers/SchemeHandler.cs
index 92ed924..e3f8a86 100644
--- a/src/Handlers/SchemeHandler.cs
+++ b/src/Handlers/SchemeHandler.cs
@@ -7,8 +7,9 @@
using CefSharp;
using System.Windows.Forms;
using System.Drawing;
+using CefSharp.Callback;
-namespace SharpBrowser {
+namespace SharpBrowser.Handlers {
internal class SchemeHandler : IResourceHandler, IDisposable {
private static string appPath = Path.GetDirectoryName(Application.ExecutablePath) + @"\";
@@ -26,32 +27,38 @@ public void Dispose() {
}
-
//
// Summary:
- // Begin processing the request.
+ // Open the response stream. - To handle the request immediately set handleRequest
+ // to true and return true. - To decide at a later time set handleRequest to false,
+ // return true, and execute callback to continue or cancel the request. - To cancel
+ // the request immediately set handleRequest to true and return false. This method
+ // will be called in sequence but not from a dedicated thread. For backwards compatibility
+ // set handleRequest to false and return false and the CefSharp.IResourceHandler.ProcessRequest(CefSharp.IRequest,CefSharp.ICallback)
+ // method will be called.
//
// Parameters:
// request:
- // The request object.
+ // request
+ //
+ // handleRequest:
+ // see main summary
//
// callback:
- // The callback used to Continue or Cancel the request (async).
+ // callback
//
// Returns:
- // To handle the request return true and call CefSharp.ICallback.Continue()
- // once the response header information is available CefSharp.ICallback.Continue()
- // can also be called from inside this method if header information is available
- // immediately). To cancel the request return false.
- public bool ProcessRequest(IRequest request, ICallback callback) {
+ // see main summary
+ public bool Open(IRequest request, out bool handleRequest, ICallback callback) {
uri = new Uri(request.Url);
fileName = uri.AbsolutePath;
// if url is blocked
- /*if (!myForm.IsURLOk(request.Url)) {
+ /*if (...request.Url....) {
- // return true so it does not open up
- return true;
+ // cancel the request - set handleRequest to true and return false
+ handleRequest = true;
+ return false;
}*/
// if url is browser file
@@ -60,8 +67,6 @@ public bool ProcessRequest(IRequest request, ICallback callback) {
if (File.Exists(fileName)) {
Task.Factory.StartNew(() => {
using (callback) {
- //var bytes = Encoding.UTF8.GetBytes(resource);
- //stream = new MemoryStream(bytes);
FileStream fStream = new FileStream(fileName, FileMode.Open, FileAccess.Read);
mimeType = ResourceHandler.GetMimeType(Path.GetExtension(fileName));
stream = fStream;
@@ -69,6 +74,8 @@ public bool ProcessRequest(IRequest request, ICallback callback) {
}
});
+ // handle the request at a later time
+ handleRequest = false;
return true;
}
}
@@ -82,12 +89,18 @@ public bool ProcessRequest(IRequest request, ICallback callback) {
callback.Continue();
}
});
+
+ // handle the request at a later time
+ handleRequest = false;
return true;
}
// by default reject
callback.Dispose();
+
+ // cancel the request - set handleRequest to true and return false
+ handleRequest = true;
return false;
}
//
@@ -111,7 +124,7 @@ public bool ProcessRequest(IRequest request, ICallback callback) {
// To redirect the request to a new URL set redirectUrl to the new Url.
public void GetResponseHeaders(IResponse response, out long responseLength, out string redirectUrl) {
- responseLength = stream.Length;
+ responseLength = stream != null ? stream.Length : 0;
redirectUrl = null;
response.StatusCode = (int)HttpStatusCode.OK;
@@ -163,6 +176,74 @@ public bool ReadResponse(Stream dataOut, out int bytesRead, ICallback callback)
return bytesRead > 0;
}
+
+ //
+ // Summary:
+ // Read response data. If data is available immediately copy up to dataOut.Length
+ // bytes into dataOut, set bytesRead to the number of bytes copied, and return true.
+ // To read the data at a later time keep a pointer to dataOut, set bytesRead to
+ // 0, return true and execute callback when the data is available (dataOut will
+ // remain valid until the callback is executed). To indicate response completion
+ // set bytesRead to 0 and return false. To indicate failure set bytesRead to < 0
+ // (e.g. -2 for ERR_FAILED) and return false. This method will be called in sequence
+ // but not from a dedicated thread. For backwards compatibility set bytesRead to
+ // -1 and return false and the ReadResponse method will be called.
+ //
+ // Parameters:
+ // dataOut:
+ // If data is available immediately copy up to System.IO.Stream.Length bytes into
+ // dataOut.
+ //
+ // bytesRead:
+ // To indicate response completion set bytesRead to 0 and return false.
+ //
+ // callback:
+ // set bytesRead to 0, return true and execute callback when the data is available
+ // (dataOut will remain valid until the callback is executed). If you have no need
+ // of the callback then Dispose of it immeduately.
+ //
+ // Returns:
+ // return true or false depending on the criteria, see summary.
+ public bool Read(Stream dataOut, out int bytesRead, IResourceReadCallback callback) {
+
+ // For backwards compatibility set bytesRead to
+ // -1 and return false and the ReadResponse method will be called.
+ bytesRead = -1;
+ return false;
+ }
+
+ //
+ // Summary:
+ // Skip response data when requested by a Range header. Skip over and discard bytesToSkip
+ // bytes of response data. - If data is available immediately set bytesSkipped to
+ // the number of of bytes skipped and return true. - To read the data at a later
+ // time set bytesSkipped to 0, return true and execute callback when the data is
+ // available. - To indicate failure set bytesSkipped to < 0 (e.g. -2 for ERR_FAILED)
+ // and return false. This method will be called in sequence but not from a dedicated
+ // thread.
+ //
+ // Parameters:
+ // bytesToSkip:
+ // number of bytes to be skipped
+ //
+ // bytesSkipped:
+ // If data is available immediately set bytesSkipped to the number of of bytes skipped
+ // and return true. To read the data at a later time set bytesSkipped to 0, return
+ // true and execute callback when the data is available.
+ //
+ // callback:
+ // To read the data at a later time set bytesSkipped to 0, return true and execute
+ // callback when the data is available.
+ //
+ // Returns:
+ // See summary
+ public bool Skip(long bytesToSkip, out long bytesSkipped, IResourceSkipCallback callback) {
+ // To indicate failure set bytesSkipped to < 0 (e.g. -2 for ERR_FAILED)
+ // and return false.
+ bytesSkipped = -2;
+ return false;
+ }
+
// Summary:
// Request processing has been canceled.
public void Cancel() {
@@ -183,5 +264,26 @@ public bool CanSetCookie(CefSharp.Cookie cookie) {
return true;
}
+ //
+ // Summary:
+ // Begin processing the request.
+ //
+ // Parameters:
+ // request:
+ // The request object.
+ //
+ // callback:
+ // The callback used to Continue or Cancel the request (async).
+ //
+ // Returns:
+ // To handle the request return true and call CefSharp.ICallback.Continue once the
+ // response header information is available CefSharp.ICallback.Continue can also
+ // be called from inside this method if header information is available immediately).
+ // To cancel the request return false.
+ public bool ProcessRequest(IRequest request, ICallback callback) {
+ return false;
+ }
+
+
}
}
\ No newline at end of file
diff --git a/src/Handlers/SchemeHandlerFactory.cs b/src/Handlers/SchemeHandlerFactory.cs
index d31d66c..06e958a 100644
--- a/src/Handlers/SchemeHandlerFactory.cs
+++ b/src/Handlers/SchemeHandlerFactory.cs
@@ -1,6 +1,6 @@
using CefSharp;
-namespace SharpBrowser {
+namespace SharpBrowser.Handlers {
internal class SchemeHandlerFactory : ISchemeHandlerFactory {
public IResourceHandler Create(IBrowser browser, IFrame frame, string schemeName, IRequest request) {
diff --git a/src/MainForm.Designer.cs b/src/MainForm.Designer.cs
index 0460d68..e9b7d9e 100644
--- a/src/MainForm.Designer.cs
+++ b/src/MainForm.Designer.cs
@@ -1,4 +1,7 @@
-namespace SharpBrowser
+using FontAwesome.Sharp;
+using System.Windows.Forms;
+
+namespace SharpBrowser
{
partial class MainForm
{
@@ -20,338 +23,548 @@ protected override void Dispose(bool disposing)
base.Dispose(disposing);
}
- #region Windows Form Designer generated code
+ #region Windows Form Designer generated code
- ///
- /// Required method for Designer support - do not modify
- /// the contents of this method with the code editor.
- ///
- private void InitializeComponent()
- {
- this.components = new System.ComponentModel.Container();
+ ///
+ /// Required method for Designer support - do not modify
+ /// the contents of this method with the code editor.
+ ///
+ private void InitializeComponent() {
+ components = new System.ComponentModel.Container();
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(MainForm));
- this.menuStripTab = new System.Windows.Forms.ContextMenuStrip(this.components);
- this.menuCloseTab = new System.Windows.Forms.ToolStripMenuItem();
- this.menuCloseOtherTabs = new System.Windows.Forms.ToolStripMenuItem();
- this.BtnRefresh = new System.Windows.Forms.Button();
- this.BtnStop = new System.Windows.Forms.Button();
- this.BtnForward = new System.Windows.Forms.Button();
- this.BtnBack = new System.Windows.Forms.Button();
- this.timer1 = new System.Windows.Forms.Timer(this.components);
- this.BtnDownloads = new System.Windows.Forms.Button();
- this.TxtURL = new System.Windows.Forms.TextBox();
- this.PanelToolbar = new System.Windows.Forms.Panel();
- this.TabPages = new FarsiLibrary.Win.FATabStrip();
- this.tabStrip1 = new FarsiLibrary.Win.FATabStripItem();
- this.tabStripAdd = new FarsiLibrary.Win.FATabStripItem();
- this.PanelStatus = new System.Windows.Forms.Panel();
- this.PanelSearch = new System.Windows.Forms.Panel();
- this.BtnNextSearch = new System.Windows.Forms.Button();
- this.BtnPrevSearch = new System.Windows.Forms.Button();
- this.BtnCloseSearch = new System.Windows.Forms.Button();
- this.TxtSearch = new System.Windows.Forms.TextBox();
- this.menuStripTab.SuspendLayout();
- this.PanelToolbar.SuspendLayout();
- ((System.ComponentModel.ISupportInitialize)(this.TabPages)).BeginInit();
- this.TabPages.SuspendLayout();
- this.PanelSearch.SuspendLayout();
- this.SuspendLayout();
- //
- // menuStripTab
- //
- this.menuStripTab.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
- this.menuCloseTab,
- this.menuCloseOtherTabs});
- this.menuStripTab.Name = "menuStripTab";
- this.menuStripTab.Size = new System.Drawing.Size(198, 52);
- //
- // menuCloseTab
- //
- this.menuCloseTab.Name = "menuCloseTab";
- this.menuCloseTab.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.F4)));
- this.menuCloseTab.Size = new System.Drawing.Size(197, 24);
- this.menuCloseTab.Text = "Close tab";
- this.menuCloseTab.Click += new System.EventHandler(this.menuCloseTab_Click);
- //
- // menuCloseOtherTabs
- //
- this.menuCloseOtherTabs.Name = "menuCloseOtherTabs";
- this.menuCloseOtherTabs.Size = new System.Drawing.Size(197, 24);
- this.menuCloseOtherTabs.Text = "Close other tabs";
- this.menuCloseOtherTabs.Click += new System.EventHandler(this.menuCloseOtherTabs_Click);
+ TabMenu = new ContextMenuStrip(components);
+ TMReload = new IconMenuItem();
+ TMClose = new IconMenuItem();
+ TMCloseOther = new IconMenuItem();
+ BtnRefresh = new IconButton();
+ BtnStop = new IconButton();
+ BtnForward = new IconButton();
+ BtnBack = new IconButton();
+ BtnDownloads = new IconButton();
+ TxtURL = new TextBox();
+ PanelToolbar = new Panel();
+ BtnMenu = new IconButton();
+ BtnHome = new IconButton();
+ TabPages = new SharpBrowser.Controls.BrowserTabStrip.BrowserTabStrip();
+ tabStrip1 = new SharpBrowser.Controls.BrowserTabStrip.BrowserTabPage();
+ PanelSearch = new Panel();
+ BtnNextSearch = new Button();
+ BtnPrevSearch = new Button();
+ BtnCloseSearch = new Button();
+ TxtSearch = new TextBox();
+ MainMenu = new ContextMenuStrip(components);
+ MMNewTab = new IconMenuItem();
+ MMNextTab = new IconMenuItem();
+ MMPrevTab = new IconMenuItem();
+ toolStripSeparator1 = new ToolStripSeparator();
+ MMPrint = new IconMenuItem();
+ MMPrintPDF = new IconMenuItem();
+ MMDownloads = new IconMenuItem();
+ MMFullscreen = new IconMenuItem();
+ MMDevTools = new IconMenuItem();
+ toolStripSeparator2 = new ToolStripSeparator();
+ MMClose = new IconMenuItem();
+ MMCloseOther = new IconMenuItem();
+ TabMenu.SuspendLayout();
+ PanelToolbar.SuspendLayout();
+ ((System.ComponentModel.ISupportInitialize)TabPages).BeginInit();
+ TabPages.SuspendLayout();
+ PanelSearch.SuspendLayout();
+ MainMenu.SuspendLayout();
+ SuspendLayout();
+ //
+ // TabMenu
+ //
+ TabMenu.ImageScalingSize = new System.Drawing.Size(20, 20);
+ TabMenu.Items.AddRange(new ToolStripItem[] { TMReload, TMClose, TMCloseOther });
+ TabMenu.Name = "menuStripTab";
+ TabMenu.Size = new System.Drawing.Size(173, 82);
+ //
+ // TMReload
+ //
+ TMReload.IconChar = IconChar.Refresh;
+ TMReload.IconColor = System.Drawing.Color.Black;
+ TMReload.IconFont = IconFont.Auto;
+ TMReload.Name = "TMReload";
+ TMReload.Size = new System.Drawing.Size(172, 26);
+ TMReload.Text = "Reload tab";
+ TMReload.Click += TMReload_Click;
+ //
+ // TMClose
+ //
+ TMClose.IconChar = IconChar.Close;
+ TMClose.IconColor = System.Drawing.Color.Black;
+ TMClose.IconFont = IconFont.Auto;
+ TMClose.Name = "TMClose";
+ TMClose.ShortcutKeyDisplayString = "Ctrl+W";
+ TMClose.Size = new System.Drawing.Size(172, 26);
+ TMClose.Text = "Close tab";
+ TMClose.Click += TMCloseTab_Click;
+ //
+ // TMCloseOther
+ //
+ TMCloseOther.IconChar = IconChar.Eraser;
+ TMCloseOther.IconColor = System.Drawing.Color.Black;
+ TMCloseOther.IconFont = IconFont.Auto;
+ TMCloseOther.Name = "TMCloseOther";
+ TMCloseOther.Size = new System.Drawing.Size(172, 26);
+ TMCloseOther.Text = "Close other tabs";
+ TMCloseOther.Click += TMCloseOtherTabs_Click;
//
// BtnRefresh
//
- this.BtnRefresh.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
- this.BtnRefresh.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
- this.BtnRefresh.ForeColor = System.Drawing.Color.White;
- this.BtnRefresh.Image = ((System.Drawing.Image)(resources.GetObject("BtnRefresh.Image")));
- this.BtnRefresh.Location = new System.Drawing.Point(878, 0);
- this.BtnRefresh.Margin = new System.Windows.Forms.Padding(3, 4, 3, 4);
- this.BtnRefresh.Name = "BtnRefresh";
- this.BtnRefresh.Size = new System.Drawing.Size(25, 30);
- this.BtnRefresh.TabIndex = 3;
- this.BtnRefresh.UseVisualStyleBackColor = true;
- this.BtnRefresh.Click += new System.EventHandler(this.bRefresh_Click);
+ BtnRefresh.BackgroundImageLayout = ImageLayout.Zoom;
+ BtnRefresh.FlatAppearance.BorderSize = 0;
+ BtnRefresh.FlatStyle = FlatStyle.Flat;
+ BtnRefresh.ForeColor = System.Drawing.Color.White;
+ BtnRefresh.IconChar = IconChar.Refresh;
+ BtnRefresh.IconColor = System.Drawing.Color.Black;
+ BtnRefresh.IconFont = IconFont.Auto;
+ BtnRefresh.IconSize = 30;
+ BtnRefresh.Location = new System.Drawing.Point(85, 5);
+ BtnRefresh.Margin = new Padding(3, 4, 3, 4);
+ BtnRefresh.Name = "BtnRefresh";
+ BtnRefresh.Size = new System.Drawing.Size(36, 34);
+ BtnRefresh.TabIndex = 3;
+ BtnRefresh.UseVisualStyleBackColor = true;
+ BtnRefresh.Click += bRefresh_Click;
//
// BtnStop
//
- this.BtnStop.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
- this.BtnStop.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
- this.BtnStop.ForeColor = System.Drawing.Color.White;
- this.BtnStop.Image = ((System.Drawing.Image)(resources.GetObject("BtnStop.Image")));
- this.BtnStop.Location = new System.Drawing.Point(878, -2);
- this.BtnStop.Margin = new System.Windows.Forms.Padding(3, 4, 3, 4);
- this.BtnStop.Name = "BtnStop";
- this.BtnStop.Size = new System.Drawing.Size(25, 30);
- this.BtnStop.TabIndex = 2;
- this.BtnStop.UseVisualStyleBackColor = true;
- this.BtnStop.Click += new System.EventHandler(this.bStop_Click);
+ BtnStop.BackgroundImageLayout = ImageLayout.Zoom;
+ BtnStop.FlatStyle = FlatStyle.Flat;
+ BtnStop.ForeColor = System.Drawing.Color.White;
+ BtnStop.IconChar = IconChar.Cancel;
+ BtnStop.IconColor = System.Drawing.Color.Black;
+ BtnStop.IconFont = IconFont.Auto;
+ BtnStop.IconSize = 30;
+ BtnStop.Location = new System.Drawing.Point(85, 5);
+ BtnStop.Margin = new Padding(3, 4, 3, 4);
+ BtnStop.Name = "BtnStop";
+ BtnStop.Size = new System.Drawing.Size(36, 34);
+ BtnStop.TabIndex = 2;
+ BtnStop.UseVisualStyleBackColor = true;
+ BtnStop.Click += bStop_Click;
//
// BtnForward
//
- this.BtnForward.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
- this.BtnForward.ForeColor = System.Drawing.Color.White;
- this.BtnForward.Image = ((System.Drawing.Image)(resources.GetObject("BtnForward.Image")));
- this.BtnForward.Location = new System.Drawing.Point(29, 0);
- this.BtnForward.Margin = new System.Windows.Forms.Padding(3, 4, 3, 4);
- this.BtnForward.Name = "BtnForward";
- this.BtnForward.Size = new System.Drawing.Size(25, 30);
- this.BtnForward.TabIndex = 1;
- this.BtnForward.UseVisualStyleBackColor = true;
- this.BtnForward.Click += new System.EventHandler(this.bForward_Click);
+ BtnForward.BackgroundImageLayout = ImageLayout.Zoom;
+ BtnForward.FlatAppearance.BorderSize = 0;
+ BtnForward.FlatStyle = FlatStyle.Flat;
+ BtnForward.ForeColor = System.Drawing.Color.White;
+ BtnForward.IconChar = IconChar.ArrowRight;
+ BtnForward.IconColor = System.Drawing.Color.Black;
+ BtnForward.IconFont = IconFont.Auto;
+ BtnForward.IconSize = 30;
+ BtnForward.Location = new System.Drawing.Point(45, 5);
+ BtnForward.Margin = new Padding(3, 4, 3, 4);
+ BtnForward.Name = "BtnForward";
+ BtnForward.Size = new System.Drawing.Size(36, 34);
+ BtnForward.TabIndex = 1;
+ BtnForward.UseVisualStyleBackColor = true;
+ BtnForward.Click += bForward_Click;
//
// BtnBack
//
- this.BtnBack.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
- this.BtnBack.ForeColor = System.Drawing.Color.White;
- this.BtnBack.Image = ((System.Drawing.Image)(resources.GetObject("BtnBack.Image")));
- this.BtnBack.Location = new System.Drawing.Point(2, 0);
- this.BtnBack.Margin = new System.Windows.Forms.Padding(3, 4, 3, 4);
- this.BtnBack.Name = "BtnBack";
- this.BtnBack.Size = new System.Drawing.Size(25, 30);
- this.BtnBack.TabIndex = 0;
- this.BtnBack.UseVisualStyleBackColor = true;
- this.BtnBack.Click += new System.EventHandler(this.bBack_Click);
- //
- // timer1
- //
- this.timer1.Interval = 50;
- this.timer1.Tick += new System.EventHandler(this.timer1_Tick);
+ BtnBack.BackgroundImageLayout = ImageLayout.Zoom;
+ BtnBack.FlatAppearance.BorderSize = 0;
+ BtnBack.FlatStyle = FlatStyle.Flat;
+ BtnBack.ForeColor = System.Drawing.Color.White;
+ BtnBack.IconChar = IconChar.ArrowLeft;
+ BtnBack.IconColor = System.Drawing.Color.Black;
+ BtnBack.IconFont = IconFont.Auto;
+ BtnBack.IconSize = 30;
+ BtnBack.Location = new System.Drawing.Point(5, 5);
+ BtnBack.Margin = new Padding(3, 4, 3, 4);
+ BtnBack.Name = "BtnBack";
+ BtnBack.Size = new System.Drawing.Size(36, 34);
+ BtnBack.TabIndex = 0;
+ BtnBack.UseVisualStyleBackColor = true;
+ BtnBack.Click += bBack_Click;
//
// BtnDownloads
//
- this.BtnDownloads.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
- this.BtnDownloads.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
- this.BtnDownloads.ForeColor = System.Drawing.Color.White;
- this.BtnDownloads.Image = ((System.Drawing.Image)(resources.GetObject("BtnDownloads.Image")));
- this.BtnDownloads.Location = new System.Drawing.Point(906, 0);
- this.BtnDownloads.Margin = new System.Windows.Forms.Padding(3, 4, 3, 4);
- this.BtnDownloads.Name = "BtnDownloads";
- this.BtnDownloads.Size = new System.Drawing.Size(25, 30);
- this.BtnDownloads.TabIndex = 4;
- this.BtnDownloads.Tag = "Downloads";
- this.BtnDownloads.UseVisualStyleBackColor = true;
- this.BtnDownloads.Click += new System.EventHandler(this.bDownloads_Click);
+ BtnDownloads.Anchor = AnchorStyles.Top | AnchorStyles.Right;
+ BtnDownloads.BackgroundImageLayout = ImageLayout.Zoom;
+ BtnDownloads.FlatAppearance.BorderSize = 0;
+ BtnDownloads.FlatStyle = FlatStyle.Flat;
+ BtnDownloads.ForeColor = System.Drawing.Color.White;
+ BtnDownloads.IconChar = IconChar.Download;
+ BtnDownloads.IconColor = System.Drawing.Color.Black;
+ BtnDownloads.IconFont = IconFont.Auto;
+ BtnDownloads.IconSize = 30;
+ BtnDownloads.Location = new System.Drawing.Point(794, 5);
+ BtnDownloads.Margin = new Padding(3, 4, 3, 4);
+ BtnDownloads.Name = "BtnDownloads";
+ BtnDownloads.Size = new System.Drawing.Size(36, 34);
+ BtnDownloads.TabIndex = 4;
+ BtnDownloads.Tag = "Downloads";
+ BtnDownloads.UseVisualStyleBackColor = true;
+ BtnDownloads.Click += bDownloads_Click;
//
// TxtURL
//
- this.TxtURL.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
- | System.Windows.Forms.AnchorStyles.Right)));
- this.TxtURL.BorderStyle = System.Windows.Forms.BorderStyle.None;
- this.TxtURL.Font = new System.Drawing.Font("Segoe UI", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
- this.TxtURL.Location = new System.Drawing.Point(60, 5);
- this.TxtURL.Margin = new System.Windows.Forms.Padding(3, 4, 3, 4);
- this.TxtURL.Name = "TxtURL";
- this.TxtURL.Size = new System.Drawing.Size(812, 27);
- this.TxtURL.TabIndex = 5;
- this.TxtURL.Click += new System.EventHandler(this.txtUrl_Click);
- this.TxtURL.TextChanged += new System.EventHandler(this.txtUrl_TextChanged);
- this.TxtURL.KeyDown += new System.Windows.Forms.KeyEventHandler(this.TxtURL_KeyDown);
+ TxtURL.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
+ TxtURL.Font = new System.Drawing.Font("Segoe UI", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, 0);
+ TxtURL.Location = new System.Drawing.Point(132, 4);
+ TxtURL.Margin = new Padding(3, 4, 3, 4);
+ TxtURL.Name = "TxtURL";
+ TxtURL.Size = new System.Drawing.Size(654, 29);
+ TxtURL.TabIndex = 5;
+ TxtURL.Click += TxtURL_Click;
+ TxtURL.Enter += TxtURL_Enter;
+ TxtURL.KeyDown += TxtURL_KeyDown;
//
// PanelToolbar
//
- this.PanelToolbar.BackColor = System.Drawing.Color.White;
- this.PanelToolbar.Controls.Add(this.TxtURL);
- this.PanelToolbar.Controls.Add(this.BtnDownloads);
- this.PanelToolbar.Controls.Add(this.BtnForward);
- this.PanelToolbar.Controls.Add(this.BtnBack);
- this.PanelToolbar.Controls.Add(this.BtnRefresh);
- this.PanelToolbar.Controls.Add(this.BtnStop);
- this.PanelToolbar.Dock = System.Windows.Forms.DockStyle.Top;
- this.PanelToolbar.Location = new System.Drawing.Point(0, 0);
- this.PanelToolbar.Margin = new System.Windows.Forms.Padding(3, 4, 3, 4);
- this.PanelToolbar.Name = "PanelToolbar";
- this.PanelToolbar.Size = new System.Drawing.Size(934, 30);
- this.PanelToolbar.TabIndex = 6;
+ PanelToolbar.BackColor = System.Drawing.Color.FromArgb(247, 247, 247);
+ PanelToolbar.Controls.Add(BtnMenu);
+ PanelToolbar.Controls.Add(BtnHome);
+ PanelToolbar.Controls.Add(BtnDownloads);
+ PanelToolbar.Controls.Add(BtnForward);
+ PanelToolbar.Controls.Add(BtnBack);
+ PanelToolbar.Controls.Add(TxtURL);
+ PanelToolbar.Controls.Add(BtnRefresh);
+ PanelToolbar.Controls.Add(BtnStop);
+ PanelToolbar.Dock = DockStyle.Top;
+ PanelToolbar.Location = new System.Drawing.Point(0, 0);
+ PanelToolbar.Margin = new Padding(3, 4, 3, 4);
+ PanelToolbar.Name = "PanelToolbar";
+ PanelToolbar.Size = new System.Drawing.Size(916, 45);
+ PanelToolbar.TabIndex = 6;
+ //
+ // BtnMenu
+ //
+ BtnMenu.Anchor = AnchorStyles.Top | AnchorStyles.Right;
+ BtnMenu.BackgroundImageLayout = ImageLayout.Zoom;
+ BtnMenu.FlatAppearance.BorderSize = 0;
+ BtnMenu.FlatAppearance.MouseDownBackColor = System.Drawing.Color.Silver;
+ BtnMenu.FlatAppearance.MouseOverBackColor = System.Drawing.Color.FromArgb(224, 224, 224);
+ BtnMenu.FlatStyle = FlatStyle.Flat;
+ BtnMenu.ForeColor = System.Drawing.Color.White;
+ BtnMenu.IconChar = IconChar.Bars;
+ BtnMenu.IconColor = System.Drawing.Color.Black;
+ BtnMenu.IconFont = IconFont.Auto;
+ BtnMenu.IconSize = 30;
+ BtnMenu.Location = new System.Drawing.Point(874, 5);
+ BtnMenu.Margin = new Padding(3, 4, 3, 4);
+ BtnMenu.Name = "BtnMenu";
+ BtnMenu.Size = new System.Drawing.Size(36, 34);
+ BtnMenu.TabIndex = 7;
+ BtnMenu.Tag = "Menu3dot";
+ BtnMenu.Text = "";
+ BtnMenu.UseVisualStyleBackColor = true;
+ BtnMenu.Click += BtnMenu_Click;
+ //
+ // BtnHome
+ //
+ BtnHome.Anchor = AnchorStyles.Top | AnchorStyles.Right;
+ BtnHome.BackgroundImageLayout = ImageLayout.Zoom;
+ BtnHome.FlatAppearance.BorderSize = 0;
+ BtnHome.FlatStyle = FlatStyle.Flat;
+ BtnHome.ForeColor = System.Drawing.Color.White;
+ BtnHome.IconChar = IconChar.House;
+ BtnHome.IconColor = System.Drawing.Color.Black;
+ BtnHome.IconFont = IconFont.Auto;
+ BtnHome.IconSize = 30;
+ BtnHome.Location = new System.Drawing.Point(834, 5);
+ BtnHome.Margin = new Padding(3, 4, 3, 4);
+ BtnHome.Name = "BtnHome";
+ BtnHome.Size = new System.Drawing.Size(36, 34);
+ BtnHome.TabIndex = 6;
+ BtnHome.Tag = "Home";
+ BtnHome.UseVisualStyleBackColor = true;
+ BtnHome.Click += BtnHome_Click;
//
// TabPages
//
- this.TabPages.ContextMenuStrip = this.menuStripTab;
- this.TabPages.Dock = System.Windows.Forms.DockStyle.Fill;
- this.TabPages.Font = new System.Drawing.Font("Segoe UI", 10.8F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
- this.TabPages.Items.AddRange(new FarsiLibrary.Win.FATabStripItem[] {
- this.tabStrip1,
- this.tabStripAdd});
- this.TabPages.Location = new System.Drawing.Point(0, 30);
- this.TabPages.Name = "TabPages";
- this.TabPages.SelectedItem = this.tabStrip1;
- this.TabPages.Size = new System.Drawing.Size(934, 621);
- this.TabPages.TabIndex = 4;
- this.TabPages.Text = "faTabStrip1";
- this.TabPages.TabStripItemSelectionChanged += new FarsiLibrary.Win.TabStripItemChangedHandler(this.OnTabsChanged);
- this.TabPages.TabStripItemClosed += new System.EventHandler(this.OnTabClosed);
- this.TabPages.MouseClick += new System.Windows.Forms.MouseEventHandler(this.tabPages_MouseClick);
+ TabPages.ContextMenuStrip = TabMenu;
+ TabPages.Dock = DockStyle.Fill;
+ TabPages.Font = new System.Drawing.Font("Segoe UI", 10.8F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, 0);
+ TabPages.Items.AddRange(new Controls.BrowserTabStrip.BrowserTabPage[] { tabStrip1 });
+ TabPages.Location = new System.Drawing.Point(0, 45);
+ TabPages.Name = "TabPages";
+ TabPages.Padding = new Padding(1, 41, 1, 1);
+ TabPages.SelectedIndex = 0;
+ TabPages.SelectedTab = tabStrip1;
+ TabPages.Size = new System.Drawing.Size(916, 427);
+ TabPages.TabIndex = 4;
+ TabPages.Text = "faTabStrip1";
+ TabPages.TabStripItemSelectionChanged += OnTabsChanged;
+ TabPages.TabStripItemClosed += OnTabClosed;
+ TabPages.TabStripNewTab += OnNewTab;
//
// tabStrip1
//
- this.tabStrip1.IsDrawn = true;
- this.tabStrip1.Name = "tabStrip1";
- this.tabStrip1.Selected = true;
- this.tabStrip1.Size = new System.Drawing.Size(932, 591);
- this.tabStrip1.TabIndex = 0;
- this.tabStrip1.Title = "Loading...";
- //
- // tabStripAdd
- //
- this.tabStripAdd.CanClose = false;
- this.tabStripAdd.IsDrawn = true;
- this.tabStripAdd.Name = "tabStripAdd";
- this.tabStripAdd.Size = new System.Drawing.Size(931, 601);
- this.tabStripAdd.TabIndex = 1;
- this.tabStripAdd.Title = "+";
- //
- // PanelStatus
- //
- this.PanelStatus.Dock = System.Windows.Forms.DockStyle.Bottom;
- this.PanelStatus.Location = new System.Drawing.Point(0, 651);
- this.PanelStatus.Name = "PanelStatus";
- this.PanelStatus.Size = new System.Drawing.Size(934, 20);
- this.PanelStatus.TabIndex = 8;
+ tabStrip1.Dock = DockStyle.Fill;
+ tabStrip1.IsDrawn = true;
+ tabStrip1.Location = new System.Drawing.Point(1, 41);
+ tabStrip1.Name = "tabStrip1";
+ tabStrip1.Selected = true;
+ tabStrip1.Size = new System.Drawing.Size(914, 385);
+ tabStrip1.TabIndex = 0;
+ tabStrip1.Title = "Loading...";
//
// PanelSearch
//
- this.PanelSearch.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
- this.PanelSearch.BackColor = System.Drawing.Color.White;
- this.PanelSearch.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
- this.PanelSearch.Controls.Add(this.BtnNextSearch);
- this.PanelSearch.Controls.Add(this.BtnPrevSearch);
- this.PanelSearch.Controls.Add(this.BtnCloseSearch);
- this.PanelSearch.Controls.Add(this.TxtSearch);
- this.PanelSearch.Location = new System.Drawing.Point(625, 41);
- this.PanelSearch.Name = "PanelSearch";
- this.PanelSearch.Size = new System.Drawing.Size(307, 40);
- this.PanelSearch.TabIndex = 9;
- this.PanelSearch.Visible = false;
+ PanelSearch.Anchor = AnchorStyles.Top | AnchorStyles.Right;
+ PanelSearch.BackColor = System.Drawing.Color.White;
+ PanelSearch.BorderStyle = BorderStyle.FixedSingle;
+ PanelSearch.Controls.Add(BtnNextSearch);
+ PanelSearch.Controls.Add(BtnPrevSearch);
+ PanelSearch.Controls.Add(BtnCloseSearch);
+ PanelSearch.Controls.Add(TxtSearch);
+ PanelSearch.Location = new System.Drawing.Point(592, 115);
+ PanelSearch.Name = "PanelSearch";
+ PanelSearch.Size = new System.Drawing.Size(307, 49);
+ PanelSearch.TabIndex = 9;
+ PanelSearch.Visible = false;
//
// BtnNextSearch
//
- this.BtnNextSearch.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
- this.BtnNextSearch.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
- this.BtnNextSearch.ForeColor = System.Drawing.Color.White;
- this.BtnNextSearch.Image = ((System.Drawing.Image)(resources.GetObject("BtnNextSearch.Image")));
- this.BtnNextSearch.Location = new System.Drawing.Point(239, 4);
- this.BtnNextSearch.Margin = new System.Windows.Forms.Padding(3, 4, 3, 4);
- this.BtnNextSearch.Name = "BtnNextSearch";
- this.BtnNextSearch.Size = new System.Drawing.Size(25, 30);
- this.BtnNextSearch.TabIndex = 9;
- this.BtnNextSearch.Tag = "Find next (Enter)";
- this.BtnNextSearch.UseVisualStyleBackColor = true;
- this.BtnNextSearch.Click += new System.EventHandler(this.BtnNextSearch_Click);
+ BtnNextSearch.Anchor = AnchorStyles.Top | AnchorStyles.Right;
+ BtnNextSearch.FlatStyle = FlatStyle.Flat;
+ BtnNextSearch.ForeColor = System.Drawing.Color.White;
+ BtnNextSearch.Image = (System.Drawing.Image)resources.GetObject("BtnNextSearch.Image");
+ BtnNextSearch.Location = new System.Drawing.Point(239, 8);
+ BtnNextSearch.Margin = new Padding(3, 4, 3, 4);
+ BtnNextSearch.Name = "BtnNextSearch";
+ BtnNextSearch.Size = new System.Drawing.Size(25, 30);
+ BtnNextSearch.TabIndex = 9;
+ BtnNextSearch.Tag = "Find next (Enter)";
+ BtnNextSearch.UseVisualStyleBackColor = true;
+ BtnNextSearch.Click += BtnNextSearch_Click;
//
// BtnPrevSearch
//
- this.BtnPrevSearch.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
- this.BtnPrevSearch.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
- this.BtnPrevSearch.ForeColor = System.Drawing.Color.White;
- this.BtnPrevSearch.Image = ((System.Drawing.Image)(resources.GetObject("BtnPrevSearch.Image")));
- this.BtnPrevSearch.Location = new System.Drawing.Point(206, 4);
- this.BtnPrevSearch.Margin = new System.Windows.Forms.Padding(3, 4, 3, 4);
- this.BtnPrevSearch.Name = "BtnPrevSearch";
- this.BtnPrevSearch.Size = new System.Drawing.Size(25, 30);
- this.BtnPrevSearch.TabIndex = 8;
- this.BtnPrevSearch.Tag = "Find previous (Shift+Enter)";
- this.BtnPrevSearch.UseVisualStyleBackColor = true;
- this.BtnPrevSearch.Click += new System.EventHandler(this.BtnPrevSearch_Click);
+ BtnPrevSearch.Anchor = AnchorStyles.Top | AnchorStyles.Right;
+ BtnPrevSearch.FlatStyle = FlatStyle.Flat;
+ BtnPrevSearch.ForeColor = System.Drawing.Color.White;
+ BtnPrevSearch.Image = (System.Drawing.Image)resources.GetObject("BtnPrevSearch.Image");
+ BtnPrevSearch.Location = new System.Drawing.Point(206, 8);
+ BtnPrevSearch.Margin = new Padding(3, 4, 3, 4);
+ BtnPrevSearch.Name = "BtnPrevSearch";
+ BtnPrevSearch.Size = new System.Drawing.Size(25, 30);
+ BtnPrevSearch.TabIndex = 8;
+ BtnPrevSearch.Tag = "Find previous (Shift+Enter)";
+ BtnPrevSearch.UseVisualStyleBackColor = true;
+ BtnPrevSearch.Click += BtnPrevSearch_Click;
//
// BtnCloseSearch
//
- this.BtnCloseSearch.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
- this.BtnCloseSearch.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
- this.BtnCloseSearch.ForeColor = System.Drawing.Color.White;
- this.BtnCloseSearch.Image = ((System.Drawing.Image)(resources.GetObject("BtnCloseSearch.Image")));
- this.BtnCloseSearch.Location = new System.Drawing.Point(272, 4);
- this.BtnCloseSearch.Margin = new System.Windows.Forms.Padding(3, 4, 3, 4);
- this.BtnCloseSearch.Name = "BtnCloseSearch";
- this.BtnCloseSearch.Size = new System.Drawing.Size(25, 30);
- this.BtnCloseSearch.TabIndex = 7;
- this.BtnCloseSearch.Tag = "Close (Esc)";
- this.BtnCloseSearch.UseVisualStyleBackColor = true;
- this.BtnCloseSearch.Click += new System.EventHandler(this.BtnClearSearch_Click);
+ BtnCloseSearch.Anchor = AnchorStyles.Top | AnchorStyles.Right;
+ BtnCloseSearch.FlatStyle = FlatStyle.Flat;
+ BtnCloseSearch.ForeColor = System.Drawing.Color.White;
+ BtnCloseSearch.Image = (System.Drawing.Image)resources.GetObject("BtnCloseSearch.Image");
+ BtnCloseSearch.Location = new System.Drawing.Point(272, 8);
+ BtnCloseSearch.Margin = new Padding(3, 4, 3, 4);
+ BtnCloseSearch.Name = "BtnCloseSearch";
+ BtnCloseSearch.Size = new System.Drawing.Size(25, 30);
+ BtnCloseSearch.TabIndex = 7;
+ BtnCloseSearch.Tag = "Close (Esc)";
+ BtnCloseSearch.UseVisualStyleBackColor = true;
+ BtnCloseSearch.Click += BtnClearSearch_Click;
//
// TxtSearch
//
- this.TxtSearch.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
- | System.Windows.Forms.AnchorStyles.Right)));
- this.TxtSearch.BorderStyle = System.Windows.Forms.BorderStyle.None;
- this.TxtSearch.Font = new System.Drawing.Font("Segoe UI", 13.8F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
- this.TxtSearch.Location = new System.Drawing.Point(10, 6);
- this.TxtSearch.Margin = new System.Windows.Forms.Padding(3, 4, 3, 4);
- this.TxtSearch.Name = "TxtSearch";
- this.TxtSearch.Size = new System.Drawing.Size(181, 31);
- this.TxtSearch.TabIndex = 6;
- this.TxtSearch.TextChanged += new System.EventHandler(this.TxtSearch_TextChanged);
- this.TxtSearch.KeyDown += new System.Windows.Forms.KeyEventHandler(this.TxtSearch_KeyDown);
+ TxtSearch.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
+ TxtSearch.BorderStyle = BorderStyle.None;
+ TxtSearch.Font = new System.Drawing.Font("Segoe UI", 13.8F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, 0);
+ TxtSearch.Location = new System.Drawing.Point(9, 8);
+ TxtSearch.Margin = new Padding(3, 4, 3, 4);
+ TxtSearch.Name = "TxtSearch";
+ TxtSearch.Size = new System.Drawing.Size(181, 25);
+ TxtSearch.TabIndex = 6;
+ TxtSearch.TextChanged += TxtSearch_TextChanged;
+ TxtSearch.KeyDown += TxtSearch_KeyDown;
+ //
+ // MainMenu
+ //
+ MainMenu.ImageScalingSize = new System.Drawing.Size(20, 20);
+ MainMenu.Items.AddRange(new ToolStripItem[] { MMNewTab, MMNextTab, MMPrevTab, toolStripSeparator1, MMPrint, MMPrintPDF, MMDownloads, MMFullscreen, MMDevTools, toolStripSeparator2, MMClose, MMCloseOther });
+ MainMenu.Name = "menuStripTab";
+ MainMenu.Size = new System.Drawing.Size(228, 276);
+ //
+ // MMNewTab
+ //
+ MMNewTab.IconChar = IconChar.Add;
+ MMNewTab.IconColor = System.Drawing.Color.Black;
+ MMNewTab.IconFont = IconFont.Auto;
+ MMNewTab.Name = "MMNewTab";
+ MMNewTab.ShortcutKeyDisplayString = "Ctrl+T";
+ MMNewTab.Size = new System.Drawing.Size(227, 26);
+ MMNewTab.Text = "New tab";
+ MMNewTab.Click += MMNewTab_Click;
+ //
+ // MMNextTab
+ //
+ MMNextTab.IconChar = IconChar.ArrowRight;
+ MMNextTab.IconColor = System.Drawing.Color.Black;
+ MMNextTab.IconFont = IconFont.Auto;
+ MMNextTab.Name = "MMNextTab";
+ MMNextTab.ShortcutKeyDisplayString = "Ctrl+Tab";
+ MMNextTab.Size = new System.Drawing.Size(227, 26);
+ MMNextTab.Text = "Next tab";
+ MMNextTab.Click += MMNextTab_Click;
+ //
+ // MMPrevTab
+ //
+ MMPrevTab.IconChar = IconChar.ArrowLeft;
+ MMPrevTab.IconColor = System.Drawing.Color.Black;
+ MMPrevTab.IconFont = IconFont.Auto;
+ MMPrevTab.Name = "MMPrevTab";
+ MMPrevTab.ShortcutKeyDisplayString = "Ctrl+Shift+Tab";
+ MMPrevTab.Size = new System.Drawing.Size(227, 26);
+ MMPrevTab.Text = "Previous tab";
+ MMPrevTab.Click += MMPrevTab_Click;
+ //
+ // toolStripSeparator1
+ //
+ toolStripSeparator1.Name = "toolStripSeparator1";
+ toolStripSeparator1.Size = new System.Drawing.Size(224, 6);
+ //
+ // MMPrint
+ //
+ MMPrint.IconChar = IconChar.Print;
+ MMPrint.IconColor = System.Drawing.Color.Black;
+ MMPrint.IconFont = IconFont.Auto;
+ MMPrint.Name = "MMPrint";
+ MMPrint.ShortcutKeyDisplayString = "Ctrl+P";
+ MMPrint.Size = new System.Drawing.Size(227, 26);
+ MMPrint.Text = "Print...";
+ MMPrint.Click += MMPrint_Click;
+ //
+ // MMPrintPDF
+ //
+ MMPrintPDF.IconChar = IconChar.FilePdf;
+ MMPrintPDF.IconColor = System.Drawing.Color.Black;
+ MMPrintPDF.IconFont = IconFont.Auto;
+ MMPrintPDF.Name = "MMPrintPDF";
+ MMPrintPDF.ShortcutKeyDisplayString = "Ctrl+Shift+P";
+ MMPrintPDF.Size = new System.Drawing.Size(227, 26);
+ MMPrintPDF.Text = "Print to PDF...";
+ MMPrintPDF.Click += MMPrintPDF_Click;
+ //
+ // MMDownloads
+ //
+ MMDownloads.IconChar = IconChar.Download;
+ MMDownloads.IconColor = System.Drawing.Color.Black;
+ MMDownloads.IconFont = IconFont.Auto;
+ MMDownloads.Name = "MMDownloads";
+ MMDownloads.Size = new System.Drawing.Size(227, 26);
+ MMDownloads.Text = "Downloads...";
+ MMDownloads.Click += MMDownloads_Click;
+ //
+ // MMFullscreen
+ //
+ MMFullscreen.IconChar = IconChar.Expand;
+ MMFullscreen.IconColor = System.Drawing.Color.Black;
+ MMFullscreen.IconFont = IconFont.Auto;
+ MMFullscreen.Name = "MMFullscreen";
+ MMFullscreen.ShortcutKeyDisplayString = "F11";
+ MMFullscreen.Size = new System.Drawing.Size(227, 26);
+ MMFullscreen.Text = "Fullscreen";
+ MMFullscreen.Click += MMFullscreen_Click;
+ //
+ // MMDevTools
+ //
+ MMDevTools.IconChar = IconChar.Code;
+ MMDevTools.IconColor = System.Drawing.Color.Black;
+ MMDevTools.IconFont = IconFont.Auto;
+ MMDevTools.Name = "MMDevTools";
+ MMDevTools.ShortcutKeyDisplayString = "F12";
+ MMDevTools.Size = new System.Drawing.Size(227, 26);
+ MMDevTools.Text = "Developer tools...";
+ MMDevTools.Click += MMDevTools_Click;
+ //
+ // toolStripSeparator2
+ //
+ toolStripSeparator2.Name = "toolStripSeparator2";
+ toolStripSeparator2.Size = new System.Drawing.Size(224, 6);
+ //
+ // MMClose
+ //
+ MMClose.IconChar = IconChar.Close;
+ MMClose.IconColor = System.Drawing.Color.Black;
+ MMClose.IconFont = IconFont.Auto;
+ MMClose.Name = "MMClose";
+ MMClose.ShortcutKeyDisplayString = "Ctrl+W";
+ MMClose.Size = new System.Drawing.Size(227, 26);
+ MMClose.Text = "Close tab";
+ MMClose.Click += MMClose_Click;
+ //
+ // MMCloseOther
+ //
+ MMCloseOther.IconChar = IconChar.Eraser;
+ MMCloseOther.IconColor = System.Drawing.Color.Black;
+ MMCloseOther.IconFont = IconFont.Auto;
+ MMCloseOther.Name = "MMCloseOther";
+ MMCloseOther.Size = new System.Drawing.Size(227, 26);
+ MMCloseOther.Text = "Close other tabs";
+ MMCloseOther.Click += MMCloseOther_Click;
//
// MainForm
//
- this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.None;
- this.ClientSize = new System.Drawing.Size(934, 671);
- this.Controls.Add(this.PanelSearch);
- this.Controls.Add(this.TabPages);
- this.Controls.Add(this.PanelToolbar);
- this.Controls.Add(this.PanelStatus);
- this.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
- this.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5);
- this.Name = "MainForm";
- this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
- this.Text = "Title";
- this.WindowState = System.Windows.Forms.FormWindowState.Maximized;
- this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.MainForm_FormClosing);
- this.Load += new System.EventHandler(this.MainForm_Load);
- this.menuStripTab.ResumeLayout(false);
- this.PanelToolbar.ResumeLayout(false);
- this.PanelToolbar.PerformLayout();
- ((System.ComponentModel.ISupportInitialize)(this.TabPages)).EndInit();
- this.TabPages.ResumeLayout(false);
- this.PanelSearch.ResumeLayout(false);
- this.PanelSearch.PerformLayout();
- this.ResumeLayout(false);
+ AutoScaleMode = AutoScaleMode.None;
+ ClientSize = new System.Drawing.Size(916, 472);
+ Controls.Add(PanelSearch);
+ Controls.Add(TabPages);
+ Controls.Add(PanelToolbar);
+ Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, 0);
+ Margin = new Padding(4, 5, 4, 5);
+ Name = "MainForm";
+ StartPosition = FormStartPosition.CenterScreen;
+ Text = "Title";
+ WindowState = FormWindowState.Maximized;
+ FormClosing += MainForm_FormClosing;
+ Load += MainForm_Load;
+ TabMenu.ResumeLayout(false);
+ PanelToolbar.ResumeLayout(false);
+ PanelToolbar.PerformLayout();
+ ((System.ComponentModel.ISupportInitialize)TabPages).EndInit();
+ TabPages.ResumeLayout(false);
+ PanelSearch.ResumeLayout(false);
+ PanelSearch.PerformLayout();
+ MainMenu.ResumeLayout(false);
+ ResumeLayout(false);
+ }
- }
- #endregion
+ #endregion
- private FarsiLibrary.Win.FATabStrip TabPages;
- private FarsiLibrary.Win.FATabStripItem tabStrip1;
- private FarsiLibrary.Win.FATabStripItem tabStripAdd;
- private System.Windows.Forms.Timer timer1;
- private System.Windows.Forms.ContextMenuStrip menuStripTab;
- private System.Windows.Forms.ToolStripMenuItem menuCloseTab;
- private System.Windows.Forms.ToolStripMenuItem menuCloseOtherTabs;
- private System.Windows.Forms.Button BtnForward;
- private System.Windows.Forms.Button BtnBack;
- private System.Windows.Forms.Button BtnStop;
- private System.Windows.Forms.Button BtnRefresh;
- private System.Windows.Forms.Button BtnDownloads;
+ private SharpBrowser.Controls.BrowserTabStrip.BrowserTabStrip TabPages;
+ private SharpBrowser.Controls.BrowserTabStrip.BrowserTabPage tabStrip1;
+ private System.Windows.Forms.ContextMenuStrip TabMenu;
+ private FontAwesome.Sharp.IconButton BtnForward;
+ private FontAwesome.Sharp.IconButton BtnBack;
+ private FontAwesome.Sharp.IconButton BtnStop;
+ private FontAwesome.Sharp.IconButton BtnRefresh;
+ private FontAwesome.Sharp.IconButton BtnDownloads;
private System.Windows.Forms.TextBox TxtURL;
private System.Windows.Forms.Panel PanelToolbar;
- private System.Windows.Forms.Panel PanelStatus;
private System.Windows.Forms.Panel PanelSearch;
private System.Windows.Forms.TextBox TxtSearch;
private System.Windows.Forms.Button BtnCloseSearch;
private System.Windows.Forms.Button BtnPrevSearch;
private System.Windows.Forms.Button BtnNextSearch;
- }
+ private FontAwesome.Sharp.IconButton BtnHome;
+ private FontAwesome.Sharp.IconButton BtnMenu;
+ private ContextMenuStrip MainMenu;
+ private IconMenuItem MMClose;
+ private IconMenuItem MMCloseOther;
+ private IconMenuItem MMNewTab;
+ private ToolStripSeparator toolStripSeparator1;
+ private IconMenuItem TMReload;
+ private IconMenuItem TMClose;
+ private IconMenuItem TMCloseOther;
+ private IconMenuItem MMDownloads;
+ private IconMenuItem MMNextTab;
+ private IconMenuItem MMPrevTab;
+ private ToolStripSeparator toolStripSeparator2;
+ private IconMenuItem MMPrint;
+ private IconMenuItem MMPrintPDF;
+ private IconMenuItem MMDevTools;
+ private IconMenuItem MMFullscreen;
+ }
}
diff --git a/src/MainForm.cs b/src/MainForm.cs
index 140fa02..31e1497 100644
--- a/src/MainForm.cs
+++ b/src/MainForm.cs
@@ -2,113 +2,63 @@
using System.Windows.Forms;
using System.Threading;
using System.Diagnostics;
-using System.Configuration;
using System.Collections.Generic;
using System.IO;
-using System.Linq;
using System.Web;
+using System.Linq;
using CefSharp;
using CefSharp.WinForms;
-using FarsiLibrary.Win;
-using Timer = System.Windows.Forms.Timer;
+using SharpBrowser.Controls.BrowserTabStrip;
using System.Drawing;
-using System.Reflection;
+using SharpBrowser.Managers;
+using SharpBrowser.Controls;
+using SharpBrowser.Handlers;
+using SharpBrowser.Config;
+using SharpBrowser.Model;
+using SharpBrowser.Utils;
namespace SharpBrowser {
///
- /// The main SharpBrowser form, supporting multiple tabs.
- /// We used the x86 version of CefSharp V51, so the app works on 32-bit and 64-bit machines.
- /// If you would only like to support 64-bit machines, simply change the DLL references.
+ /// The main SharpBrowser form supporting multiple tabs, and handling all the managers required for the browser.
///
internal partial class MainForm : Form {
- private string appPath = Path.GetDirectoryName(Application.ExecutablePath) + @"\";
-
public static MainForm Instance;
- public static string Branding = "SharpBrowser";
- public static string UserAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.109 Safari/537.36";
- public static string HomepageURL = "https://www.google.com";
- public static string NewTabURL = "about:blank";
- public static string DownloadsURL = "sharpbrowser://storage/downloads.html";
- public static string FileNotFoundURL = "sharpbrowser://storage/errors/notFound.html";
- public static string CannotConnectURL = "sharpbrowser://storage/errors/cannotConnect.html";
- public static string SearchURL = "https://www.google.com/search?q=";
-
- public bool WebSecurity = true;
- public bool CrossDomainSecurity = true;
- public bool WebGL = true;
- public bool ApplicationCache = true;
-
-
-
public MainForm() {
-
Instance = this;
InitializeComponent();
- InitBrowser();
-
- SetFormTitle(null);
-
}
private void MainForm_Load(object sender, EventArgs e) {
- InitAppIcon();
- InitTooltips(this.Controls);
- InitHotkeys();
-
- }
- #region App Icon
+ // init managers
+ ConfigManager.Init(BrowserConfig.AppID);
+ DownloadManager.Init();
+ BrowserManager.Init(this);
+ InitFavIcons();
- ///
- /// embedding the resource using the Visual Studio designer results in a blurry icon.
- /// the best way to get a non-blurry icon for Windows 7 apps.
- ///
- private void InitAppIcon() {
- assembly = Assembly.GetAssembly(typeof(MainForm));
- Icon = new Icon(GetResourceStream("sharpbrowser.ico"), new Size(64, 64));
- }
-
- public static Assembly assembly = null;
- public Stream GetResourceStream(string filename, bool withNamespace = true) {
- try {
- return assembly.GetManifestResourceStream("SharpBrowser.Resources." + filename);
- } catch (System.Exception ex) { }
- return null;
- }
-
- #endregion
-
- #region Tooltips & Hotkeys
+ // init the browser UI
+ InitBrowser();
+ SetFormTitle(null);
+ IconManager.Init(this);
+ InitTooltips(this.Controls);
+ HotkeyManager.Init(this);
+ InitDisabledIcons();
+ InitToolbar();
- ///
- /// these hotkeys work when the user is focussed on the .NET form and its controls,
- /// AND when the user is focussed on the browser (CefSharp portion)
- ///
- private void InitHotkeys() {
+ // start with the last tabs
+ LoadLastTabs();
- // browser hotkeys
- KeyboardHandler.AddHotKey(this, CloseActiveTab, Keys.W, true);
- KeyboardHandler.AddHotKey(this, CloseActiveTab, Keys.Escape, true);
- KeyboardHandler.AddHotKey(this, AddBlankWindow, Keys.N, true);
- KeyboardHandler.AddHotKey(this, AddBlankTab, Keys.T, true);
- KeyboardHandler.AddHotKey(this, RefreshActiveTab, Keys.F5);
- KeyboardHandler.AddHotKey(this, OpenDeveloperTools, Keys.F12);
- KeyboardHandler.AddHotKey(this, NextTab, Keys.Tab, true);
- KeyboardHandler.AddHotKey(this, PrevTab, Keys.Tab, true, true);
+ }
- // search hotkeys
- KeyboardHandler.AddHotKey(this, OpenSearch, Keys.F, true);
- KeyboardHandler.AddHotKey(this, CloseSearch, Keys.Escape);
- KeyboardHandler.AddHotKey(this, StopActiveTab, Keys.Escape);
- }
+ #region Tooltips & Hotkeys
///
/// we activate all the tooltips stored in the Tag property of the buttons
@@ -133,81 +83,69 @@ public void InitTooltips(System.Windows.Forms.Control.ControlCollection parent)
#endregion
- #region Web Browser & Tabs
+ #region Browser UI
- private FATabStripItem newStrip;
- private FATabStripItem downloadsStrip;
- private string currentFullURL;
- private string currentCleanURL;
- private string currentTitle;
-
- public HostHandler host;
- private DownloadHandler dHandler;
- private ContextMenuHandler mHandler;
- private LifeSpanHandler lHandler;
- private KeyboardHandler kHandler;
- private RequestHandler rHandler;
+ private void SetFormTitle(string tabName) {
- ///
- /// this is done just once, to globally initialize CefSharp/CEF
- ///
- private void InitBrowser() {
+ if (tabName.CheckIfValid()) {
- CefSettings settings = new CefSettings();
+ this.Text = tabName + " - " + BrowserConfig.Branding;
+ currentTitle = tabName;
- settings.RegisterScheme(new CefCustomScheme {
- SchemeName = "sharpbrowser",
- SchemeHandlerFactory = new SchemeHandlerFactory()
- });
+ }
+ else {
- settings.UserAgent = UserAgent;
+ this.Text = BrowserConfig.Branding;
+ currentTitle = "New Tab";
+ }
- settings.IgnoreCertificateErrors = true;
-
- settings.CachePath = GetAppDir("Cache");
+ }
- Cef.Initialize(settings);
+ private void SetFormURL(string URL) {
- dHandler = new DownloadHandler(this);
- lHandler = new LifeSpanHandler(this);
- mHandler = new ContextMenuHandler(this);
- kHandler = new KeyboardHandler(this);
- rHandler = new RequestHandler(this);
+ currentFullURL = URL;
+ currentCleanURL = URLUtils.CleanURL(URL);
- InitDownloads();
+ TxtURL.Text = currentCleanURL;
- host = new HostHandler(this);
+ if (CurTab != null) {
+ CurTab.CurURL = currentFullURL;
+ }
- AddNewBrowser(tabStrip1, HomepageURL);
+ CloseSearch();
}
- ///
- /// this is done every time a new tab is openede
- ///
- private void ConfigureBrowser(ChromiumWebBrowser browser) {
- BrowserSettings config = new BrowserSettings();
+ #endregion
- config.FileAccessFromFileUrls = (!CrossDomainSecurity).ToCefState();
- config.UniversalAccessFromFileUrls = (!CrossDomainSecurity).ToCefState();
- config.WebSecurity = WebSecurity.ToCefState();
- config.WebGl = WebGL.ToCefState();
- config.ApplicationCache = ApplicationCache.ToCefState();
+ #region Web Browser & Tabs
- browser.BrowserSettings = config;
+ private string currentFullURL;
+ private string currentCleanURL;
+ private string currentTitle;
+
+ ///
+ /// this is done just once, to globally initialize CefSharp/CEF
+ ///
+ private void InitBrowser() {
+
+ AddNewBrowser(tabStrip1, BrowserConfig.HomepageURL);
}
+ ///
+ /// this is done every time a new tab is openede
+ ///
+ private void ConfigureBrowser(ChromiumWebBrowser browser) {
+ browser.BrowserSettings = BrowserConfig.GetCefConfig();
- private static string GetAppDir(string name) {
- string winXPDir = @"C:\Documents and Settings\All Users\Application Data\";
- if (Directory.Exists(winXPDir)) {
- return winXPDir + Branding + @"\" + name + @"\";
- }
- return @"C:\ProgramData\" + Branding + @"\" + name + @"\";
+ }
+ private void InitFavIcons() {
+ FavIconManager.OnLoaded = Manager_OnFavIconLoaded;
+ FavIconManager.Init();
}
private void LoadURL(string url) {
@@ -223,28 +161,31 @@ private void LoadURL(string url) {
newUrl = "http://localhost/";
- } else if (url.CheckIfFilePath() || url.CheckIfFilePath2()) {
+ }
+ else if (url.CheckIfFilePath() || url.CheckIfFilePath2()) {
newUrl = url.PathToURL();
- } else {
+ }
+ else {
Uri.TryCreate(url, UriKind.Absolute, out outUri);
- if (!(urlLower.StartsWith("http") || urlLower.StartsWith("sharpbrowser"))) {
+ if (!(urlLower.StartsWith("http") || urlLower.StartsWith(BrowserConfig.InternalScheme))) {
if (outUri == null || outUri.Scheme != Uri.UriSchemeFile) newUrl = "http://" + url;
}
- if (urlLower.StartsWith("sharpbrowser:") ||
+ if (urlLower.Contains("://") ||
// load URL if it seems valid
(Uri.TryCreate(newUrl, UriKind.Absolute, out outUri)
&& ((outUri.Scheme == Uri.UriSchemeHttp || outUri.Scheme == Uri.UriSchemeHttps) && newUrl.Contains(".") || outUri.Scheme == Uri.UriSchemeFile))) {
- } else {
+ }
+ else {
// run search if unknown URL
- newUrl = SearchURL + HttpUtility.UrlEncode(url);
+ newUrl = BrowserConfig.SearchURL + HttpUtility.UrlEncode(url);
}
@@ -262,98 +203,42 @@ private void LoadURL(string url) {
}
- private void SetFormTitle(string tabName) {
-
- if (tabName.CheckIfValid()) {
-
- this.Text = tabName + " - " + Branding;
- currentTitle = tabName;
-
- } else {
-
- this.Text = Branding;
- currentTitle = "New Tab";
- }
-
- }
-
- private void SetFormURL(string URL) {
-
- currentFullURL = URL;
- currentCleanURL = CleanURL(URL);
-
- TxtURL.Text = currentCleanURL;
-
- CurTab.CurURL = currentFullURL;
-
- CloseSearch();
-
- }
-
- private string CleanURL(string url) {
- if (url.BeginsWith("about:")) {
- return "";
- }
- url = url.RemovePrefix("http://");
- url = url.RemovePrefix("https://");
- url = url.RemovePrefix("file://");
- url = url.RemovePrefix("/");
- return url.DecodeURL();
- }
- private bool IsBlank(string url) {
- return (url == "" || url == "about:blank");
- }
- private bool IsBlankOrSystem(string url) {
- return (url == "" || url.BeginsWith("about:") || url.BeginsWith("chrome:") || url.BeginsWith("sharpbrowser:"));
- }
-
- public void AddBlankWindow() {
-
- // open a new instance of the browser
-
- ProcessStartInfo info = new ProcessStartInfo(Application.ExecutablePath, "");
- //info.WorkingDirectory = workingDir ?? exePath.GetPathDir(true);
- info.LoadUserProfile = true;
-
- info.UseShellExecute = false;
- info.RedirectStandardError = true;
- info.RedirectStandardOutput = true;
- info.RedirectStandardInput = true;
-
- Process.Start(info);
- }
- public void AddBlankTab() {
- AddNewBrowserTab("");
- this.InvokeOnParent(delegate() {
- TxtURL.Focus();
- });
- }
-
- public ChromiumWebBrowser AddNewBrowserTab(string url, bool focusNewTab = true, string refererUrl = null) {
- return (ChromiumWebBrowser)this.Invoke((Func)delegate {
+ public ChromiumWebBrowser AddNewBrowserTab(string url, bool focusNewTab = true, string refererUrl = null, bool skipIfUrlAlreadyOpen = false, bool focusOnAddressBar = false) {
+ return Invoke((Func)delegate {
// check if already exists
- foreach (FATabStripItem tab in TabPages.Items) {
- SharpTab tab2 = (SharpTab)tab.Tag;
- if (tab2 != null && (tab2.CurURL == url)) {
- TabPages.SelectedItem = tab;
- return tab2.Browser;
+ if (skipIfUrlAlreadyOpen) {
+ foreach (BrowserTabPage tab in TabPages.Items) {
+ BrowserTab tab2 = (BrowserTab)tab.Tag;
+ if (tab2 != null && (tab2.CurURL == url)) {
+ TabPages.SelectedTab = tab;
+ return tab2.Browser;
+ }
}
}
- FATabStripItem tabStrip = new FATabStripItem();
+ // new tab button and select it
+ BrowserTabPage tabStrip = new BrowserTabPage();
tabStrip.Title = "New Tab";
- TabPages.Items.Insert(TabPages.Items.Count - 1, tabStrip);
- newStrip = tabStrip;
+ TabPages.AddTab(tabStrip, focusNewTab);
- SharpTab newTab = AddNewBrowser(newStrip, url);
+ // new browser
+ BrowserTab newTab = AddNewBrowser(tabStrip, url);
newTab.RefererURL = refererUrl;
- if (focusNewTab) timer1.Enabled = true;
+
+ // focus on address bar
+ if (focusOnAddressBar) {
+ Thread.Sleep(1000);
+ TxtURL.Focus();
+ }
+
return newTab.Browser;
});
}
- private SharpTab AddNewBrowser(FATabStripItem tabStrip, String url) {
- if (url == "") url = NewTabURL;
+
+ Panel pnlToolbarOverlay;
+ private BrowserTab AddNewBrowser(BrowserTabPage tabStrip, String url) {
+ if (url == "") url = BrowserConfig.NewTabURL;
ChromiumWebBrowser browser = new ChromiumWebBrowser(url);
// set config
@@ -362,22 +247,25 @@ private SharpTab AddNewBrowser(FATabStripItem tabStrip, String url) {
// set layout
browser.Dock = DockStyle.Fill;
tabStrip.Controls.Add(browser);
+ pnlToolbarOverlay = new Panel() {
+ Width = PanelToolbar.Width,
+ Height = PanelToolbar.Height,
+ Dock = DockStyle.Top,
+ };
+ tabStrip.Controls.Add(pnlToolbarOverlay);
browser.BringToFront();
// add events
- browser.StatusMessage += Browser_StatusMessage;
+ //browser.StatusMessage += Browser_StatusMessage;
browser.LoadingStateChanged += Browser_LoadingStateChanged;
+ browser.FrameLoadEnd += Browser_FrameLoadEnd;
browser.TitleChanged += Browser_TitleChanged;
browser.LoadError += Browser_LoadError;
browser.AddressChanged += Browser_URLChanged;
- browser.DownloadHandler = dHandler;
- browser.MenuHandler = mHandler;
- browser.LifeSpanHandler = lHandler;
- browser.KeyboardHandler = kHandler;
- browser.RequestHandler = rHandler;
+ BrowserManager.SetupHandlers(browser);
// new tab obj
- SharpTab tab = new SharpTab {
+ BrowserTab tab = new BrowserTab() {
IsOpen = true,
Browser = browser,
Tab = tabStrip,
@@ -390,15 +278,17 @@ private SharpTab AddNewBrowser(FATabStripItem tabStrip, String url) {
// save tab obj in tabstrip
tabStrip.Tag = tab;
- if (url.StartsWith("sharpbrowser:")) {
- browser.RegisterAsyncJsObject("host", host);
+ // handle downloads page
+ if (url.StartsWith(BrowserConfig.InternalScheme + ":")) {
+ browser.JavascriptObjectRepository.Register("host", BrowserManager._HostHandler, BindingOptions.DefaultBinder);
}
+
return tab;
}
- public SharpTab GetTabByBrowser(IWebBrowser browser) {
- foreach (FATabStripItem tab2 in TabPages.Items) {
- SharpTab tab = (SharpTab)(tab2.Tag);
+ public BrowserTab GetTabByBrowser(IWebBrowser browser) {
+ foreach (BrowserTabPage tab2 in TabPages.Items) {
+ BrowserTab tab = (BrowserTab)(tab2.Tag);
if (tab != null && tab.Browser == browser) {
return tab;
}
@@ -406,122 +296,245 @@ public SharpTab GetTabByBrowser(IWebBrowser browser) {
return null;
}
- public void RefreshActiveTab() {
- CurBrowser.Load(CurBrowser.Address);
- }
- public void CloseActiveTab() {
- if (CurTab != null/* && TabPages.Items.Count > 2*/) {
-
- // remove tab and save its index
- int index = TabPages.Items.IndexOf(TabPages.SelectedItem);
- TabPages.RemoveTab(TabPages.SelectedItem);
+ private void OnTabClosed(object sender, EventArgs e) {
- // keep tab at same index focussed
- if ((TabPages.Items.Count - 1) > index) {
- TabPages.SelectedItem = TabPages.Items[index];
- }
+ // if the very last tab is closed
+ if (TabPages.Items.Count < 1) {
+ OnLastTabClosed();
}
- }
- private void OnTabClosed(object sender, EventArgs e) {
-
}
- private void OnTabClosing(FarsiLibrary.Win.TabStripItemClosingEventArgs e) {
-
- // exit if invalid tab
- if (CurTab == null){
- e.Cancel = true;
- return;
- }
+ private void OnLastTabClosed() {
- // add a blank tab if the very last tab is closed!
- if (TabPages.Items.Count <= 2) {
- AddBlankTab();
- //e.Cancel = true;
- }
+ // close the window
+ this.Close();
+ // the new tab is bugged so this is disabled
+ //AddNewTabInternal(BrowserConfig.NewTabURL, null);
}
- private void StopActiveTab() {
- CurBrowser.Stop();
- }
+ public void StopActiveTab() => CurBrowser.Stop();
private bool IsOnFirstTab() {
- return TabPages.SelectedItem == TabPages.Items[0];
+ return TabPages.SelectedTab == TabPages.Items[0];
}
private bool IsOnLastTab() {
- return TabPages.SelectedItem == TabPages.Items[TabPages.Items.Count - 2];
+ return TabPages.SelectedTab == TabPages.Items[TabPages.Items.Count - 1];
}
- private int CurIndex {
+ private int LastIndex {
get {
- return TabPages.Items.IndexOf(TabPages.SelectedItem);
+ return TabPages.Items.Count - 1;
}
- set {
- TabPages.SelectedItem = TabPages.Items[value];
+ }
+
+ public ChromiumWebBrowser CurBrowser {
+ get {
+ if (TabPages.SelectedTab != null && TabPages.SelectedTab.Tag != null) {
+ return ((BrowserTab)TabPages.SelectedTab.Tag).Browser;
+ }
+ else {
+ return null;
+ }
}
}
- private int LastIndex {
+
+ public BrowserTab CurTab {
get {
- return TabPages.Items.Count - 2;
+ if (TabPages.SelectedTab != null && TabPages.SelectedTab.Tag != null) {
+ return ((BrowserTab)TabPages.SelectedTab.Tag);
+ }
+ else {
+ return null;
+ }
}
}
+ public List GetAllTabs() {
+ List tabs = new List();
+ foreach (BrowserTabPage tabPage in TabPages.Items) {
+ if (tabPage.Tag != null) {
+ tabs.Add((BrowserTab)tabPage.Tag);
+ }
+ }
+ return tabs;
+ }
+
+ public bool IsFavIconLoaded(ChromiumWebBrowser browser) {
+ var tab = GetTabByBrowser(browser);
+ return (tab != null && tab.FavIcon != null);
+ }
+
+ private void SetTabTitle(ChromiumWebBrowser browser, string text) {
+
+ text = text.Trim();
+ if (URLUtils.IsBlank(text)) {
+ text = "New Tab";
+ }
+
+ // save text
+ browser.Tag = text;
+
+ // get tab of given browser
+ BrowserTabPage tabStrip = (BrowserTabPage)browser.Parent;
+ if (tabStrip != null) //fix error, when fast hit on close button
+ tabStrip.Title = text;
+
+ // if current tab
+ if (browser == CurBrowser) {
+
+ SetFormTitle(text);
- private void NextTab() {
- if (IsOnLastTab()) {
- CurIndex = 0;
- } else {
- CurIndex++;
}
}
- private void PrevTab() {
- if (IsOnFirstTab()) {
- CurIndex = LastIndex;
- } else {
- CurIndex--;
+
+ public void InvokeIfNeeded(Action action) {
+ if (this.InvokeRequired) {
+ this.BeginInvoke(action);
+ }
+ else {
+ action.Invoke();
}
}
- public ChromiumWebBrowser CurBrowser {
- get {
- if (TabPages.SelectedItem != null && TabPages.SelectedItem.Tag != null) {
- return ((SharpTab)TabPages.SelectedItem.Tag).Browser;
- } else {
- return null;
- }
+ public void WaitForBrowserToInitialize(ChromiumWebBrowser browser) {
+ while (!browser.IsBrowserInitialized) {
+ Thread.Sleep(100);
}
}
- public SharpTab CurTab {
- get {
- if (TabPages.SelectedItem != null && TabPages.SelectedItem.Tag != null) {
- return ((SharpTab)TabPages.SelectedItem.Tag);
- } else {
- return null;
+ private void EnableBackButton(bool canGoBack) {
+ InvokeIfNeeded(() => BtnBack.Enabled = canGoBack);
+ }
+ private void EnableForwardButton(bool canGoForward) {
+ InvokeIfNeeded(() => BtnForward.Enabled = canGoForward);
+ }
+
+ private async void OnNewTab(object o, EventArgs e) {
+ AddBlankTab();
+ }
+ private async void OnTabsChanged(TabStripItemChangedEventArgs e) {
+ ChromiumWebBrowser browser = null;
+
+ try {
+ // apparently this 'fix' reduces frequent exceptions
+ if (e.Item.Controls.Count >= 1 && e.Item.Controls[0] as ChromiumWebBrowser != null)
+ browser = ((ChromiumWebBrowser)e.Item.Controls[0]);
+ }
+ catch (System.Exception ex) {
+ }
+
+
+ if (e.ChangeType == BrowserTabStripItemChangeTypes.SelectionChanged) {
+ Tabs_OnSwitchedTab();
+
+ }
+
+ if (e.ChangeType == BrowserTabStripItemChangeTypes.Removed) {
+ if (browser != null) {
+ browser.Dispose();
}
}
+
}
- public int CurTabLoadingDur {
- get {
- if (TabPages.SelectedItem != null && TabPages.SelectedItem.Tag != null) {
- int loadTime = (int)(DateTime.Now - CurTab.DateCreated).TotalMilliseconds;
- return loadTime;
- } else {
- return 0;
+
+ private void TMReload_Click(object sender, EventArgs e) {
+ RefreshActiveTab();
+ }
+ private void TMCloseTab_Click(object sender, EventArgs e) {
+ CloseActiveTab();
+ }
+
+ private void TMCloseOtherTabs_Click(object sender, EventArgs e) {
+ CloseOtherTabs();
+ }
+
+
+ private void bBack_Click(object sender, EventArgs e) { Back(); }
+
+
+ private void bForward_Click(object sender, EventArgs e) { Forward(); }
+
+
+ private void bDownloads_Click(object sender, EventArgs e) {
+ OpenDownloads();
+ }
+
+ private void bRefresh_Click(object sender, EventArgs e) => RefreshActiveTab();
+
+ private void bStop_Click(object sender, EventArgs e) => StopActiveTab();
+
+
+ #endregion
+
+ #region Web Browser Events
+
+ private ChromiumWebBrowser Tabs_OnSwitchedTab() {
+ ChromiumWebBrowser browser = CurBrowser;
+ if (browser != null) {
+
+ // load the text/URL from this tab into the window
+ SetFormURL(browser.Address);
+ SetFormTitle(browser.Tag.ConvertToString() ?? "New Tab");
+
+ EnableBackButton(browser.CanGoBack);
+ EnableForwardButton(browser.CanGoForward);
+
+ // focus on the browser
+ // FIX: important for hotkeys to work (for example a chain of Ctrl+W, Ctrl+W)
+ browser.Focus();
+ }
+ else {
+
+ // when a new tab is just created, the browser does not exist, so show default text/URL
+ SetFormURL("");
+ SetFormTitle("Loading...");
+
+ EnableBackButton(false);
+ EnableForwardButton(false);
+
+ }
+
+ return browser;
+ }
+
+ private void Browser_FrameLoadEnd(object sender, FrameLoadEndEventArgs e) {
+
+ // for any tab, even background tabs, download the favicon
+ if (e.Frame.IsMain) {
+
+ if (!URLUtils.IsBlankOrSystem(e.Url)) {
+
+ FavIconManager.LoadFavicon(sender as ChromiumWebBrowser, false);
}
}
}
- private void Browser_URLChanged(object sender, AddressChangedEventArgs e) {
+ private void Manager_OnFavIconLoaded(ChromiumWebBrowser browser, byte[] iconData) {
InvokeIfNeeded(() => {
+ var tab = GetTabByBrowser(browser);
+ if (tab != null && tab.Tab != null) {
+
+ Bitmap bitmap = null;
+ if (iconData != null) {
+ bitmap = new Bitmap(new MemoryStream(iconData));
+ }
+ tab.FavIcon = bitmap;
+ tab.Tab.Image = bitmap;
+ }
+
+ });
+ }
+
+ private void Browser_URLChanged(object sender, AddressChangedEventArgs e) {
+ InvokeIfNeeded(() => {
// if current tab
if (sender == CurBrowser) {
- if (!Utils.IsFocussed(TxtURL)) {
+ if (!WinFormsUtils.IsFocussed(TxtURL)) {
SetFormURL(e.Address);
}
@@ -554,30 +567,11 @@ private void Browser_TitleChanged(object sender, TitleChangedEventArgs e) {
});
}
- private void SetTabTitle(ChromiumWebBrowser browser, string text) {
-
- text = text.Trim();
- if (IsBlank(text)) {
- text = "New Tab";
- }
-
- // save text
- browser.Tag = text;
-
- // get tab of given browser
- FATabStripItem tabStrip = (FATabStripItem)browser.Parent;
- tabStrip.Title = text;
-
-
- // if current tab
- if (browser == CurBrowser) {
+ private void Browser_LoadingStateChanged(object sender, LoadingStateChangedEventArgs e) {
- SetFormTitle(text);
+ var browser = sender as ChromiumWebBrowser;
- }
- }
-
- private void Browser_LoadingStateChanged(object sender, LoadingStateChangedEventArgs e) {
+ // if its the current tab, update browser UI based on its state
if (sender == CurBrowser) {
EnableBackButton(e.CanGoBack);
@@ -588,7 +582,8 @@ private void Browser_LoadingStateChanged(object sender, LoadingStateChangedEvent
// set title
//SetTabTitle();
- } else {
+ }
+ else {
// after loaded / stopped
InvokeIfNeeded(() => {
@@ -597,166 +592,138 @@ private void Browser_LoadingStateChanged(object sender, LoadingStateChangedEvent
});
}
}
- }
-
- public void InvokeIfNeeded(Action action) {
- if (this.InvokeRequired) {
- this.BeginInvoke(action);
- } else {
- action.Invoke();
- }
- }
-
- private void Browser_StatusMessage(object sender, StatusMessageEventArgs e) {
- }
- public void WaitForBrowserToInitialize(ChromiumWebBrowser browser) {
- while (!browser.IsBrowserInitialized) {
- Thread.Sleep(100);
+ // for any tab, check favicons
+ if (!URLUtils.IsBlankOrSystem(browser.Address)) {
+ if (!IsFavIconLoaded(browser)) {
+ FavIconManager.LoadFavicon(sender as ChromiumWebBrowser, true);
+ }
}
- }
- private void EnableBackButton(bool canGoBack) {
- InvokeIfNeeded(() => BtnBack.Enabled = canGoBack);
- }
- private void EnableForwardButton(bool canGoForward) {
- InvokeIfNeeded(() => BtnForward.Enabled = canGoForward);
}
- private void OnTabsChanged(TabStripItemChangedEventArgs e) {
+ private void Browser_StatusMessage(object sender, StatusMessageEventArgs e) { }
- ChromiumWebBrowser browser = null;
- try {
- browser = ((ChromiumWebBrowser)e.Item.Controls[0]);
- } catch (System.Exception ex) { }
-
-
- if (e.ChangeType == FATabStripItemChangeTypes.SelectionChanged) {
- if (TabPages.SelectedItem == tabStripAdd) {
- AddBlankTab();
- } else {
-
- browser = CurBrowser;
+ #endregion
- SetFormURL(browser.Address);
- SetFormTitle(browser.Tag.ConvertToString() ?? "New Tab");
+ #region Web Browser Commands
+ public void AddBlankWindow() {
- EnableBackButton(browser.CanGoBack);
- EnableForwardButton(browser.CanGoForward);
+ // DISABLED BECAUSE 2 CEFSHARP INSTANCES CAUSES A CRASH
- }
- }
+ /*// open a new instance of the browser
- if (e.ChangeType == FATabStripItemChangeTypes.Removed) {
- if (e.Item == downloadsStrip) downloadsStrip = null;
- if (browser != null) {
- browser.Dispose();
- }
- }
+ ProcessStartInfo info = new ProcessStartInfo(Application.ExecutablePath, "");
+ //info.WorkingDirectory = workingDir ?? exePath.GetPathDir(true);
+ info.LoadUserProfile = true;
- if (e.ChangeType == FATabStripItemChangeTypes.Changed) {
- if (browser != null) {
- if (currentFullURL != "about:blank") {
- browser.Focus();
- }
- }
- }
+ info.UseShellExecute = false;
+ info.RedirectStandardError = true;
+ info.RedirectStandardOutput = true;
+ info.RedirectStandardInput = true;
+ Process.Start(info);*/
}
-
- private void timer1_Tick(object sender, EventArgs e) {
- TabPages.SelectedItem = newStrip;
- timer1.Enabled = false;
+ public void AddBlankTab() {
+ AddNewBrowserTab(BrowserConfig.NewTabURL, true, null, false, true);
}
- private void menuCloseTab_Click(object sender, EventArgs e) {
- CloseActiveTab();
+ public void Back() {
+ CurBrowser.Back();
}
-
- private void menuCloseOtherTabs_Click(object sender, EventArgs e) {
- List listToClose = new List();
- foreach (FATabStripItem tab in TabPages.Items) {
- if (tab != tabStripAdd && tab != TabPages.SelectedItem) listToClose.Add(tab);
+ public void Forward() {
+ CurBrowser.Forward();
+ }
+ public void OpenDownloads() {
+ AddNewBrowserTab(BrowserConfig.DownloadsURL, true, null, true);
+ }
+ public void OpenDeveloperTools() {
+ CurBrowser.ShowDevTools();
+ }
+ public void CloseOtherTabs() {
+ List listToClose = new List();
+ foreach (BrowserTabPage tab in TabPages.Items) {
+ if (tab != TabPages.SelectedTab) listToClose.Add(tab);
}
- foreach (FATabStripItem tab in listToClose) {
+ foreach (BrowserTabPage tab in listToClose) {
TabPages.RemoveTab(tab);
}
-
}
- public List CancelRequests {
- get {
- return downloadCancelRequests;
- }
- }
+ public void RefreshActiveTab() => CurBrowser.Load(CurBrowser.Address);
- private void bBack_Click(object sender, EventArgs e) {
- CurBrowser.Back();
- }
+ public void CloseActiveTab() {
- private void bForward_Click(object sender, EventArgs e) {
- CurBrowser.Forward();
- }
+ // if any tab is open
+ var curTab = TabPages.SelectedTab;
+ if (CurTab != null) {
- private void txtUrl_TextChanged(object sender, EventArgs e) {
+ // if this is the last tab, open a new tab also
+ if (TabPages.Items.Count <= 1) {
+ OnLastTabClosed();
+ }
- }
+ // remove tab and save its index
+ int index = TabPages.Items.IndexOf(curTab);
+ TabPages.RemoveTab(curTab);
- private void bDownloads_Click(object sender, EventArgs e) {
- AddNewBrowserTab(DownloadsURL);
+ // keep tab at same index focussed
+ if (TabPages.Items.Count > 1) {
+ if ((TabPages.Items.Count - 1) > index) {
+ TabPages.SelectedTab = TabPages.Items[index];
+ }
+ }
+ }
}
-
- private void bRefresh_Click(object sender, EventArgs e) {
- RefreshActiveTab();
+ public void NextTab() {
+ if (IsOnLastTab()) {
+ TabPages.SelectedIndex = 0;
+ }
+ else {
+ TabPages.SelectedIndex++;
+ }
}
-
- private void bStop_Click(object sender, EventArgs e) {
- StopActiveTab();
+ public void PrevTab() {
+ if (IsOnFirstTab()) {
+ TabPages.SelectedIndex = LastIndex;
+ }
+ else {
+ TabPages.SelectedIndex--;
+ }
+ }
+ public void Print() {
+ CurBrowser.Print();
+ }
+ public void PrintToPDF() {
+ ContextMenuHandler.SaveAsPDF(CurBrowser.GetBrowser());
}
- private void TxtURL_KeyDown(object sender, KeyEventArgs e) {
-
- // if ENTER or CTRL+ENTER pressed
- if (e.IsHotkey(Keys.Enter) || e.IsHotkey(Keys.Enter, true)) {
- LoadURL(TxtURL.Text);
- // im handling this
- e.Handled = true;
- e.SuppressKeyPress = true;
- // defocus from url textbox
- this.Focus();
- }
+ #endregion
- // if full URL copied
- if (e.IsHotkey(Keys.C, true) && Utils.IsFullySelected(TxtURL)) {
+ #region Fullscreen
- // copy the real URL, not the pretty one
- Clipboard.SetText(CurBrowser.Address, TextDataFormat.UnicodeText);
+ private FormWindowState oldWindowState;
+ private FormBorderStyle oldBorderStyle;
+ private bool isFullScreen = false;
+ public void ToggleFullscreen() {
- // im handling this
- e.Handled = true;
- e.SuppressKeyPress = true;
+ if (!isFullScreen) {
+ oldWindowState = this.WindowState;
+ oldBorderStyle = this.FormBorderStyle;
+ this.FormBorderStyle = FormBorderStyle.None;
+ this.WindowState = FormWindowState.Maximized;
+ isFullScreen = true;
}
- }
-
- private void txtUrl_Click(object sender, EventArgs e) {
- if (!Utils.HasSelection(TxtURL)) {
- TxtURL.SelectAll();
+ else {
+ this.FormBorderStyle = oldBorderStyle;
+ this.WindowState = oldWindowState;
+ isFullScreen = false;
}
}
- private void OpenDeveloperTools() {
- CurBrowser.ShowDevTools();
- }
-
- private void tabPages_MouseClick(object sender, MouseEventArgs e) {
- /*if (e.Button == System.Windows.Forms.MouseButtons.Right) {
- tabPages.GetTabItemByPoint(this.mouse
- }*/
- }
-
#endregion
#region Download Queue
@@ -764,100 +731,109 @@ private void tabPages_MouseClick(object sender, MouseEventArgs e) {
private void MainForm_FormClosing(object sender, FormClosingEventArgs e) {
// ask user if they are sure
- if (DownloadsInProgress()) {
+ if (DownloadManager.DownloadsInProgress()) {
if (MessageBox.Show("Downloads are in progress. Cancel those and exit?", "Confirm exit", MessageBoxButtons.YesNo, MessageBoxIcon.Question) != DialogResult.Yes) {
e.Cancel = true;
return;
}
}
+ // save tabs
+ SaveTabsBeforeClosing();
+
// dispose all browsers
try {
foreach (TabPage tab in TabPages.Items) {
ChromiumWebBrowser browser = (ChromiumWebBrowser)tab.Controls[0];
browser.Dispose();
}
- } catch (System.Exception ex) { }
+ }
+ catch (System.Exception ex) { }
}
- public Dictionary downloads;
- public Dictionary downloadNames;
- public List downloadCancelRequests;
-
///
- /// we must store download metadata in a list, since CefSharp does not
+ /// open a new tab with the downloads URL
///
- private void InitDownloads() {
+ private void btnDownloads_Click(object sender, EventArgs e) => OpenDownloads();
- downloads = new Dictionary();
- downloadNames = new Dictionary();
- downloadCancelRequests = new List();
+ #endregion
- }
+ #region Toolbar
- public Dictionary Downloads {
- get {
- return downloads;
- }
- }
+ private void InitToolbar() {
+ TxtURL.ToBordered();
+ PanelToolbar.Dock = DockStyle.None;
+ PanelToolbar.BringToFront();
+ PanelToolbar.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
+ PanelToolbar.Location = new Point(0, TabPages.TabButton_Height + 1); //for different dpi, need stable way to get it.
+ PanelToolbar.Width = this.Width;
+ PanelToolbar.Width = pnlToolbarOverlay.Width;
- public void UpdateDownloadItem(DownloadItem item) {
- lock (downloads) {
+ if (Debugger.IsAttached)
+ pnlToolbarOverlay.BackColor = Color.Cyan;
- // SuggestedFileName comes full only in the first attempt so keep it somewhere
- if (item.SuggestedFileName != "") {
- downloadNames[item.Id] = item.SuggestedFileName;
- }
+ new CircularDownloadProgress(BtnDownloads);
+ }
- // Set it back if it is empty
- if (item.SuggestedFileName == "" && downloadNames.ContainsKey(item.Id)) {
- item.SuggestedFileName = downloadNames[item.Id];
- }
+ private void InitDisabledIcons() {
+ BtnBack.EnabledChanged += (s1, e1) => SetIconByState(s1);
+ BtnForward.EnabledChanged += (s1, e1) => SetIconByState(s1);
+ BtnStop.EnabledChanged += (s1, e1) => SetIconByState(s1);
+ BtnRefresh.EnabledChanged += (s1, e1) => SetIconByState(s1);
+ BtnDownloads.EnabledChanged += (s1, e1) => SetIconByState(s1);
+ BtnHome.EnabledChanged += (s1, e1) => SetIconByState(s1);
+ BtnMenu.EnabledChanged += (s1, e1) => SetIconByState(s1);
+ }
+ private async void SetIconByState(object senderBtn) {
+ var faBtn = senderBtn as FontAwesome.Sharp.IconButton;
+ //faBtn.IconColor = faBtn.Enabled ? Color.Black : PanelToolbar.BackColor.ChangeColorBrightness(0);
+ faBtn.IconColor = faBtn.Enabled ? Color.Black : Color.Black.ChangeColorBrightness(0.8);
+ }
+
+ #endregion
- downloads[item.Id] = item;
+ #region Address Bar
- //UpdateSnipProgress();
- }
- }
+ private void TxtURL_KeyDown(object sender, KeyEventArgs e) {
- public string CalcDownloadPath(DownloadItem item) {
+ // if ENTER or CTRL+ENTER pressed
+ if (e.IsHotkey(Keys.Enter) || e.IsHotkey(Keys.Enter, true)) {
+ LoadURL(TxtURL.Text);
- string itemName = item.SuggestedFileName != null ? item.SuggestedFileName.GetAfterLast(".") + " file" : "downloads";
+ // im handling this
+ e.Handled = true;
+ e.SuppressKeyPress = true;
- string path = null;
- if (path != null) {
- return path;
+ // defocus from url textbox
+ this.Focus();
}
- return null;
- }
+ // if full URL copied
+ if (e.IsHotkey(Keys.C, true) && WinFormsUtils.IsFullySelected(TxtURL)) {
- public bool DownloadsInProgress() {
- foreach (DownloadItem item in downloads.Values) {
- if (item.IsInProgress) {
- return true;
- }
+ // copy the real URL, not the pretty one
+ Clipboard.SetText(CurBrowser.Address, TextDataFormat.UnicodeText);
+
+ // im handling this
+ e.Handled = true;
+ e.SuppressKeyPress = true;
}
- return false;
}
- ///
- /// open a new tab with the downloads URL
- ///
- private void btnDownloads_Click(object sender, EventArgs e) {
- OpenDownloadsTab();
+ private bool TxtURL_JustEntered = false;
+ private void TxtURL_Enter(object sender, EventArgs e) {
+ TxtURL.SelectAll();
+ TxtURL_JustEntered = true;
}
-
- public void OpenDownloadsTab() {
- if (downloadsStrip != null && ((ChromiumWebBrowser)downloadsStrip.Controls[0]).Address == DownloadsURL) {
- TabPages.SelectedItem = downloadsStrip;
- } else {
- ChromiumWebBrowser brw = AddNewBrowserTab(DownloadsURL);
- downloadsStrip = (FATabStripItem)brw.Parent;
+ private void TxtURL_Click(object sender, EventArgs e) {
+ if (TxtURL_JustEntered) {
+ TxtURL.SelectAll();
}
+ TxtURL_JustEntered = false;
}
+
#endregion
#region Search Bar
@@ -865,57 +841,51 @@ public void OpenDownloadsTab() {
bool searchOpen = false;
string lastSearch = "";
- private void OpenSearch() {
+ public void OpenSearch() {
if (!searchOpen) {
searchOpen = true;
- InvokeIfNeeded(delegate() {
+ InvokeIfNeeded(delegate () {
PanelSearch.Visible = true;
TxtSearch.Text = lastSearch;
TxtSearch.Focus();
TxtSearch.SelectAll();
});
- } else {
- InvokeIfNeeded(delegate() {
+ }
+ else {
+ InvokeIfNeeded(delegate () {
TxtSearch.Focus();
TxtSearch.SelectAll();
});
}
}
- private void CloseSearch() {
+ public void CloseSearch() {
if (searchOpen) {
searchOpen = false;
- InvokeIfNeeded(delegate() {
+ InvokeIfNeeded(delegate () {
PanelSearch.Visible = false;
CurBrowser.GetBrowser().StopFinding(true);
});
}
}
- private void BtnClearSearch_Click(object sender, EventArgs e) {
- CloseSearch();
- }
+ private void BtnClearSearch_Click(object sender, EventArgs e) => CloseSearch();
- private void BtnPrevSearch_Click(object sender, EventArgs e) {
- FindTextOnPage(false);
- }
- private void BtnNextSearch_Click(object sender, EventArgs e) {
- FindTextOnPage(true);
- }
+ private void BtnPrevSearch_Click(object sender, EventArgs e) => FindTextOnPage(false);
+ private void BtnNextSearch_Click(object sender, EventArgs e) => FindTextOnPage(true);
- private void FindTextOnPage(bool next = true) {
+ public void FindTextOnPage(bool next = true) {
bool first = lastSearch != TxtSearch.Text;
lastSearch = TxtSearch.Text;
if (lastSearch.CheckIfValid()) {
- CurBrowser.GetBrowser().Find(0, lastSearch, true, false, !first);
- } else {
+ CurBrowser.GetBrowser().Find(lastSearch, true, false, !first);
+ }
+ else {
CurBrowser.GetBrowser().StopFinding(true);
}
TxtSearch.Focus();
}
- private void TxtSearch_TextChanged(object sender, EventArgs e) {
- FindTextOnPage(true);
- }
+ private void TxtSearch_TextChanged(object sender, EventArgs e) => FindTextOnPage(true);
private void TxtSearch_KeyDown(object sender, KeyEventArgs e) {
if (e.IsHotkey(Keys.Enter)) {
@@ -926,53 +896,84 @@ private void TxtSearch_KeyDown(object sender, KeyEventArgs e) {
}
}
+
+
#endregion
+ #region Home Button
+ private void BtnHome_Click(object sender, EventArgs e) => CurBrowser.Load(BrowserConfig.HomepageURL);
+ #endregion
+ #region Main Menu Button
- }
-}
+ private void BtnMenu_Click(object sender, EventArgs e) {
+ var buttonScreenPoint = BtnMenu.PointToScreen(Point.Empty);
+ int x = buttonScreenPoint.X + BtnMenu.Width - MainMenu.Width;
+ int y = buttonScreenPoint.Y + BtnMenu.Height;
-///
-/// POCO created for holding data per tab
-///
-internal class SharpTab {
+ MainMenu.Show(x, y);
+ }
- public bool IsOpen;
- public string OrigURL;
- public string CurURL;
- public string Title;
+ private void MMNewTab_Click(object sender, EventArgs e) => AddBlankTab();
+ private void MMNewWindow_Click(object sender, EventArgs e) => AddBlankWindow();
+ private void MMNextTab_Click(object sender, EventArgs e) => NextTab();
+ private void MMPrevTab_Click(object sender, EventArgs e) => PrevTab();
- public string RefererURL;
+ private void MMDownloads_Click(object sender, EventArgs e) => OpenDownloads();
+ private void MMPrint_Click(object sender, EventArgs e) => Print();
+ private void MMPrintPDF_Click(object sender, EventArgs e) => PrintToPDF();
- public DateTime DateCreated;
+ private void MMClose_Click(object sender, EventArgs e) => CloseActiveTab();
+ private void MMCloseOther_Click(object sender, EventArgs e) => CloseOtherTabs();
- public FATabStripItem Tab;
- public ChromiumWebBrowser Browser;
+ private void MMDevTools_Click(object sender, EventArgs e) => OpenDeveloperTools();
+ private void MMFullscreen_Click(object sender, EventArgs e) => ToggleFullscreen();
+ #endregion
-}
+ #region Saved Settings
-///
-/// POCO for holding hotkey data
-///
-internal class SharpHotKey {
+ private void LoadLastTabs() {
+ if (BrowserConfig.SaveOpenTabs) {
- public Keys Key;
- public int KeyCode;
- public bool Ctrl;
- public bool Shift;
- public bool Alt;
+ // load last tabs
+ var tabs = ConfigManager.GetString("browser.lastTabs", "").Split("||");
- public Action Callback;
+ // open them all
+ var added = false;
+ foreach (var url in tabs) {
+ if (url.Length > 0) {
+ AddNewBrowserTab(url, false);
+ added = true;
+ }
+ }
+
+ // close the default tab if tabs were restored
+ if (added) {
+ CloseActiveTab();
+ }
+
+ // switch to the last active tab
+ TabPages.SelectedIndex = ConfigManager.GetInt("browser.lastTab", 0);
+ }
+ }
+ private void SaveTabsBeforeClosing() {
+ if (BrowserConfig.SaveOpenTabs) {
+
+ // get current URLs
+ var urls = TabPages.Tabs.Select(t => (t.Tag as BrowserTab).CurURL).ToList().Join("||");
+
+ // save in settings
+ ConfigManager.Set("browser.lastTabs", urls);
+ ConfigManager.Set("browser.lastTab", TabPages.SelectedIndex);
+ ConfigManager.SaveSettings();
+ }
+ }
+
+ #endregion
- public SharpHotKey(Action callback, Keys key, bool ctrl = false, bool shift = false, bool alt = false) {
- Callback = callback;
- Key = key;
- KeyCode = (int)key;
- Ctrl = ctrl;
- Shift = shift;
- Alt = alt;
- }
+
+
+ }
}
\ No newline at end of file
diff --git a/src/MainForm.resx b/src/MainForm.resx
index 9487f86..89fa46a 100644
--- a/src/MainForm.resx
+++ b/src/MainForm.resx
@@ -1,17 +1,17 @@
-
@@ -117,89 +117,78 @@
System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
- 325, 17
+
+ 856, 17
-
-
-
- iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
- YQUAAAEZSURBVDhPxVRbEQIxDKwDJCABCfzwxXBXCUhAAlJOAgJoDwlIQMJJgGw7LUlf9AfITKcznXST
- TbJR6mc2zFppOyltbtkZ5m1/Hod5QwB3Anu2DwWCL8wFJv/MdtdVHxgPZi4xsAAsgY32rECPH7xpuxSz
- F4DekdOcqnVywe0jA40fvAOPWgfDp9Gc2hmO5vh2oIa0rAYmmoIagXKoWQuQ+4Y/4e6fpb977u06UuY0
- ehSBmro/1Idomg2nHJ3lQ4NYM0ktDJD0mkltidIqoaZCEGzcAkgAQaNlglU6aiVAH2ByskM2MNx+DqVK
- wpIoUIZayjqtbR/RjIDo0/c1Q8frGTOtE03szKIBBIcbnP3CSJfAw72HMnx75l9XQGc65ZPKTwAAAABJ
- RU5ErkJggg==
-
-
-
-
- iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
- YQUAAAEtSURBVDhPvZTbDcIwDEW9ASMwAiMwAiMwAiMwAr+8pI7ACB2BETpCRii+lZ06r8ZfVIpUqHN8
- r+OY6F/Pg2j3Ijrxuj6Jxmwd3ToA4nVjwLy1OOZzJzpsggFjyLcHM99DEyrKJg3m35PYTewBAHUWyu9l
- CaRGanNoWQGQY4N1geRJvAQtMGT3wgBSMA4w7uMPZ2P1XANWlA1Sc1W7upJaLQrfRPscWINpDO8ZxNlq
- W4tc1IJ3bcEAtWKiEHMgo1XXgyHW9mzcq1msQg8MABWTuOM/L3ooqKEXJodStpptG8lo+6zZk7Z+SduI
- 9NqVa8KyVksbG8CKzVBk5TiUJLt6cy1uOSC5p7H7pa5QbseXnUIBSj0TB4De+Jq648tmwgSRHksGAW5G
- V5V7+joCf9RfGvLkc7XEAAAAAElFTkSuQmCC
-
-
-
-
- iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
- YQUAAAEWSURBVDhPvZRNEcIwEIXjAAlIQAIXTgxNJCABCUhAAhIQQFIkIAEJlVB22ybk522bXtiZXDrJ
- 1/dedqPUX+rotsrYhzKuo9WXy76Utpc6LU1rZFAOp58enhsZrO0ZK2Kl9i2qhcSm3YuwU7sbzhh3h3u0
- u5ZMQ7mgvPLNGNql1lkBDJ8zI6t5TgiaXBKrEIHDRXTK2/beCig5DBXb1e5W1w4gUwjky1lTxn2CO6yQ
- Wqe2xux/zR/Osc35DHuajPRHOYwvL9Q4HWDEpm+LMNpXZB9nEcPzPiyUTT/l+U9KnBSaV18SDE7K3Gjx
- yzP2Knh9QOMnSmsuKESyBPPk0T5+CAYYgarfw1guB80H2a5faxu/tqelfV9C2Z1KUaQMeQAAAABJRU5E
- rkJggg==
-
-
-
-
- iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
- YQUAAAEHSURBVDhPvVTbDcIwEMsGjMAIjMAPX4gmIzACIzACI3QEBiApI3QERmCEckfaKJf6+vjpSZEq
- wTm2a9eYTeYc9sb5p3HhS6cbH/821t+WcakapwOV4HTp6bXTga2/YkbhQ4xblS1ErJqjstAmFo6kIgts
- uI8x4Z+JVS6Jn6Gn5LWQfmkOwHgJxhRcqBXATr4kpixuRswUuWmPfk8j5BZgU9kolUFAzuCayZVBwMWB
- 7bchoA0P4SHnMZ8oTWnNEHayKk1sh6zYWlAmJcZxGxaBgm7T3sh7rSk5U62asClTwWU5MavAx7mYlS8I
- V62XPQc2mBrl6zXjL8/aeP2x2WheZLnD4cu2nB+yNJ4saRMhYwAAAABJRU5ErkJggg==
-
-
-
- 238, 17
+
+ 17, 17
-
-
- iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
- YQUAAADWSURBVDhPY2AY8sDIyOi+sbHxfxAGsSn2EMwwGD1qIOEQAIYVPxCvB+L9UAyOECQME19vaGio
- T9BEkIHA2HyPHhnY+EQZCLIRpJAIQ+MJug5ZAQFDSTMMZjC6oSBXE+VNoCJ5YBjlAzXUI2OQZpihMMOg
- fBR1IL0gM+A+BCqejy3QodmOH6QYaikowuBZEVkPyAy4gTiSBzz/GhgY+IMwLsOgBu8nykAcyQeUFkFp
- FVRgzIdaRL6BQAP6QWENtSweSJ8H+ZJgGBKTuJGKNkQYkpRA6a0YAGJH+ATjKEoQAAAAAElFTkSuQmCC
-
-
+
+ 124, 17
+
+
+ 224, 17
+
+
- iVBORw0KGgoAAAANSUhEUgAAABkAAAAZCAYAAADE6YVjAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
- YQUAAACfSURBVEhLY2AYBaMhMExDwHefP4PfnnyifAdSB1JPEvDbE8/gv/c/FM/Hq9d/73y4Wp99+sTZ
- 47VXHskC/BYhWwBx1HsGl938xFnkv+c8QYswLQBZgt/XKLaDXIPPIootgNmG26L7BH1JXHhBVeG2CBZX
- JAYRLtvxWgSMO6IjmpD3sFpETQuwxhEtLECxCJhMqRZEhIJwVH40BAZFCAAAcuCqYT80zm4AAAAASUVO
- RK5CYII=
+ iVBORw0KGgoAAAANSUhEUgAAABkAAAAZCAYAAADE6YVjAAAABGdBTUEAALGPC/xhBQAAAJpJREFUSEtj
+ GAWjYLgC333+DH578qE8/ACkDqSeJOC3J57Bf+9/KJ4PFcUOQPIwtT779KGiBIDXXnm4JgTGbhGyBRD8
+ nsFlNz9UlgDw33MeTTMIo1qEaQGmGrwA5Bp8FlFsAQzgtug+FjEyLIAB3BYhYwosgAG8FgHFiY5oQgCr
+ RdS0AAZQLKKFBTAAtggYBzSzYBSMgkEIGBgAcuCqYV2//8YAAAAASUVORK5CYII=
- iVBORw0KGgoAAAANSUhEUgAAABkAAAAZCAYAAADE6YVjAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
- YQUAAACXSURBVEhLY2AYBaMhMHhCwG9PPG0d4793PoP/3v9APJ82FiEsAFlCA4swLaCyRaA4gLgcF6Yw
- 6AhbQKGPsFqw5zyD1155Bn8gjekzEn2EywKX3fzgVAWiKbII7FL08Ae6HGYBLO3issh3nz1xydtvTz7C
- IiwW4LaI1CDb2w8MkvUYPkB3JsRH6xn8gOpHwWgIjIYA2SEAAOtGqKV2Jt9uAAAAAElFTkSuQmCC
+ iVBORw0KGgoAAAANSUhEUgAAABkAAAAZCAYAAADE6YVjAAAABGdBTUEAALGPC/xhBQAAAIpJREFUSEtj
+ GAWjYBABvz3xUBaNgP/e+UD8H0zTBCAsgGEqW4RpAZUtAsUBdgtgmEKLCFsAw2RahNWCPecZvPbKg2kM
+ OVItwmWBy25+sDyIpsgisEvRNSNZAAO4LPLdZw9VQQD47clHaMRiAQxgWkRqkO3tBxqwHqcFMACxaD1Y
+ /SgYBaOATMDAAADrRqilMw6anwAAAABJRU5ErkJggg==
- iVBORw0KGgoAAAANSUhEUgAAABkAAAAZCAYAAADE6YVjAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
- YQUAAADTSURBVEhL7ZTBDYMwDEW9QUfoCIzQS09VCyN0lI7CICWs0FEyAs0nJBTsNDJCnGIpQjgJz/62
- ISpWFDhegev7RE33ocZYuveVGAD82Me5TeYBw7Q4KALimVbHuZnzD4CDOABnLCF7ldXdUwR5v5MoZuAB
- KUmzUBkUMpufmwEhghwI+7tYbV6CdAPBv4vJRU53nRr6HzCD1F0VIkkDWi6dmyk1aJx21qauBlORxWbQ
- gjjE0qO/LOTG+yIQLQRfG6de8e9SyxVCxsXcoCEYrGJFgbUCX35H/c2nacnTAAAAAElFTkSuQmCC
+ iVBORw0KGgoAAAANSUhEUgAAABkAAAAZCAYAAADE6YVjAAAABGdBTUEAALGPC/xhBQAAAMZJREFUSEtj
+ GAWjYACAy25+Bv895xn8975n8NmnDxVFBSBxkDxIHVkAYsF/KMa0CG4BXM18qAyRwGuvPJJmGEZYhGkB
+ RB7ke5KA3554NEMgBkHEMS1A9ynRALtFmJhsC2CAkEUgeaoAv7312C0AilMFYI9kGKYgLmAAvwUwTEaq
+ ggHcFszHFAPmKZItAud2LBbAIhlrYiDVIkxL3jP47rOHykIAiI+ihhzfgHM9uGghruwi2QIYAGkklHpA
+ jgHhUTAKUAEDAwB+R/3NjLhB/QAAAABJRU5ErkJggg==
+
+ 1047, 17
+
+
+ 354, 17
+
+
+ 17, 54
+
+
+ 136, 54
+
+
+ 253, 54
+
+
+ 354, 54
+
+
+ 1159, 17
+
+
+ 599, 54
+
+
+ 476, 54
+
+
+ 616, 17
+
+
+ 721, 17
+
+
+ 102
+
\ No newline at end of file
diff --git a/src/Managers/BrowserManager.cs b/src/Managers/BrowserManager.cs
new file mode 100644
index 0000000..a6fe8f5
--- /dev/null
+++ b/src/Managers/BrowserManager.cs
@@ -0,0 +1,77 @@
+using CefSharp.WinForms;
+using CefSharp;
+using SharpBrowser.Handlers;
+using System.IO;
+using SharpBrowser.Config;
+using SharpBrowser.Utils;
+
+namespace SharpBrowser.Managers {
+ internal static class BrowserManager {
+
+ public static HostHandler _HostHandler;
+
+ private static DownloadHandler dHandler;
+ private static ContextMenuHandler mHandler;
+ private static LifeSpanHandler lHandler;
+ private static KeyboardHandler kHandler;
+ private static RequestHandler rHandler;
+ private static PermissionHandler pHandler;
+
+ public static void Init(MainForm form) {
+
+ if (Cef.IsInitialized != true) {
+ CefSettings settings = new CefSettings();
+
+ settings.RegisterScheme(new CefCustomScheme {
+ SchemeName = BrowserConfig.InternalScheme,
+ SchemeHandlerFactory = new SchemeHandlerFactory()
+ });
+
+ //------------------------------------------------------------
+ // FIX: this prevents a crash if 2 CefSharp apps are opened at once
+
+ // init cache dirs in AppData Roaming
+ var rcPath = Path.Combine(ConfigManager.AppDataPath, "CefCache");
+ // fix: CachePath MUST be a child of the RootCachePath as of CEF 128+
+ var cPath = Path.Combine(rcPath, "_TempCache");
+
+ // create cache dirs
+ rcPath.EnsureFolderExists();
+ cPath.EnsureFolderExists();
+
+ settings.RootCachePath = rcPath;
+ settings.CachePath = cPath;
+ //------------------------------------------------------------
+
+ BrowserConfig.GetCefSettings(settings);
+
+ Cef.Initialize(settings);
+
+ }
+
+ if (dHandler == null) {
+
+ dHandler = new DownloadHandler(form);
+ lHandler = new LifeSpanHandler(form);
+ mHandler = new ContextMenuHandler(form);
+ kHandler = new KeyboardHandler(form);
+ rHandler = new RequestHandler(form);
+ pHandler = new PermissionHandler();
+ _HostHandler = new HostHandler(form);
+
+ }
+ }
+
+ ///
+ /// Register our handlers with the given CefSharp browser instance.
+ ///
+ public static void SetupHandlers(ChromiumWebBrowser browser) {
+ browser.DownloadHandler = dHandler;
+ browser.MenuHandler = mHandler;
+ browser.LifeSpanHandler = lHandler;
+ browser.KeyboardHandler = kHandler;
+ browser.RequestHandler = rHandler;
+ browser.PermissionHandler = pHandler;
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Managers/ConfigManager.cs b/src/Managers/ConfigManager.cs
new file mode 100644
index 0000000..700d8f6
--- /dev/null
+++ b/src/Managers/ConfigManager.cs
@@ -0,0 +1,123 @@
+
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Timers;
+using Newtonsoft.Json;
+using SharpBrowser.Utils;
+
+namespace SharpBrowser.Managers {
+
+ ///
+ /// App config manager which saves app-level settings in a JSON file.
+ ///
+ public static class ConfigManager {
+
+ public static bool InitDone;
+ public static string AppDataPath;
+ private static string SettingsFilePath;
+ private static Dictionary SettingsDict;
+ private static bool SettingsChanged = false;
+ private static Timer SaveTimer;
+
+ ///
+ /// Loads existing settings from the AppData folder if they exist.
+ /// Starts a timer that saves settings every second if changes have occurred.
+ ///
+ public static void Init(string appName) {
+ if (SettingsDict == null) {
+ AppDataPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), appName);
+ AppDataPath.EnsureFolderExists();
+ SettingsFilePath = Path.Combine(AppDataPath, "settings.json");
+
+ SettingsDict = LoadSettings();
+ InitDone = true;
+
+ SaveTimer = new Timer(1000);
+ SaveTimer.Elapsed += SaveTimerElapsed;
+ SaveTimer.Start();
+ }
+ }
+
+ ///
+ /// Returns the setting for the given key, with an optional default value
+ ///
+ public static object Get(string key, object defaultVal = null) {
+ if (SettingsDict == null) throw new Exception("You need to call ZConfig.Init() first!");
+ if (SettingsDict.ContainsKey(key)) return SettingsDict[key];
+ return defaultVal;
+ }
+
+ ///
+ /// Returns the integer setting for the given key
+ ///
+ public static int GetInt(string key, int defaultVal = 0) {
+ var val = Convert.ToInt32(Get(key, defaultVal));
+ return val == 0 ? defaultVal : val;
+ }
+
+ ///
+ /// Returns the double setting for the given key
+ ///
+ public static double GetDouble(string key, double defaultVal = 0.0) {
+ var val = Convert.ToDouble(Get(key, defaultVal));
+ return val == 0 ? defaultVal : val;
+ }
+
+ ///
+ /// Returns the string setting for the given key
+ ///
+ public static string GetString(string key, string defaultVal = "") {
+ var value = Get(key, defaultVal);
+ if (value == null) return defaultVal;
+ return value is string valString ? valString : value.ToString();
+ }
+
+ ///
+ /// Returns the boolean setting for the given key
+ ///
+ public static bool GetBool(string key, bool defaultVal = false) {
+ var val = GetString(key, defaultVal.ToString());
+ return val == "true" || val == "1";
+ }
+
+ ///
+ /// Saves a setting by key, and persists it to disk within 1 second.
+ ///
+ public static void Set(string key, object value) {
+ if (SettingsDict == null) throw new Exception("Call ConfigManager.Init() first!");
+ SettingsDict[key] = value;
+ SettingsChanged = true;
+ }
+
+ ///
+ /// Returns the settings from the JSON file or an empty dictionary if the file doesn't exist
+ ///
+ private static Dictionary LoadSettings() {
+ if (File.Exists(SettingsFilePath)) {
+ var json = File.ReadAllText(SettingsFilePath);
+ return JsonConvert.DeserializeObject>(json) ?? new Dictionary();
+ }
+ return new Dictionary();
+ }
+
+ ///
+ /// Saves the settings to the JSON file
+ ///
+ public static void SaveSettings() {
+ var json = JsonConvert.SerializeObject(SettingsDict, Formatting.Indented);
+ File.WriteAllText(SettingsFilePath, json);
+ SettingsChanged = false;
+ }
+
+ ///
+ /// Timer event handler that checks if settings have changed and saves them
+ ///
+ private static void SaveTimerElapsed(object sender, ElapsedEventArgs e) {
+ if (SettingsChanged) {
+ SaveSettings();
+ }
+ }
+ }
+
+}
diff --git a/src/Managers/DownloadManager.cs b/src/Managers/DownloadManager.cs
new file mode 100644
index 0000000..f273e64
--- /dev/null
+++ b/src/Managers/DownloadManager.cs
@@ -0,0 +1,67 @@
+using CefSharp;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace SharpBrowser.Managers {
+ ///
+ /// DownloadManager stores download metadata in a list, since CefSharp does not.
+ ///
+ internal static class DownloadManager {
+
+ private static Dictionary downloads;
+ private static Dictionary downloadNames;
+ private static List downloadCancelRequests;
+
+ public static Dictionary Downloads => downloads;
+ public static string CalcDownloadPath(DownloadItem item) => item.SuggestedFileName;
+ public static List CancelRequests => downloadCancelRequests;
+
+ public static void Init() {
+
+ downloads = new Dictionary();
+ downloadNames = new Dictionary();
+ downloadCancelRequests = new List();
+
+ }
+
+ public static void UpdateDownloadItem(DownloadItem item) {
+ lock (downloads) {
+
+ // SuggestedFileName comes full only in the first attempt so keep it somewhere
+ if (item.SuggestedFileName != "") {
+ downloadNames[item.Id] = item.SuggestedFileName;
+ }
+
+ // Set it back if it is empty
+ if (item.SuggestedFileName == "" && downloadNames.ContainsKey(item.Id)) {
+ item.SuggestedFileName = downloadNames[item.Id];
+ }
+
+ downloads[item.Id] = item;
+
+ //UpdateSnipProgress();
+ }
+ }
+
+ public static bool DownloadsInProgress() {
+ foreach (DownloadItem item in downloads.Values) {
+ if (item.IsInProgress) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public static void Cancel(int downloadId) {
+ lock (downloadCancelRequests) {
+ if (!downloadCancelRequests.Contains(downloadId)) {
+ downloadCancelRequests.Add(downloadId);
+ }
+ }
+ }
+
+ }
+}
diff --git a/src/Managers/FavIconManager.cs b/src/Managers/FavIconManager.cs
new file mode 100644
index 0000000..7b2a2d4
--- /dev/null
+++ b/src/Managers/FavIconManager.cs
@@ -0,0 +1,248 @@
+using CefSharp;
+using CefSharp.WinForms;
+using SharpBrowser.Utils;
+using System;
+using System.Collections.Concurrent;
+using System.Drawing;
+using System.Drawing.Imaging;
+using System.IO;
+using System.Linq;
+using System.Net.Http;
+using System.Security.Policy;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows.Shapes;
+using static System.Windows.Forms.DataFormats;
+using Path = System.IO.Path;
+
+namespace SharpBrowser.Managers {
+
+ ///
+ /// Downloads and caches favicons for any given URL.
+ ///
+ /// The first time it will be slow as we have to:
+ /// 1. Check if the website has a favicon at the default path.
+ /// 2. Parse the HTML and look for 'link' tags that might link to an icon.
+ /// 3. Download the icon and store the bitmap file data.
+ ///
+ /// We use byte[] for cache storage instead of Bitmap,
+ /// because storing as Bitmap causes a lot of GDI errors during rendering.
+ ///
+ internal static class FavIconManager {
+
+ ///
+ /// Callback to parent.
+ ///
+ public static Action OnLoaded;
+
+ ///
+ /// Thread-safe cache with concurrent dictionary
+ ///
+ private static readonly ConcurrentDictionary FaviconCache = new ConcurrentDictionary();
+ ///
+ /// Reuse HttpClient for better performance
+ ///
+ private static readonly HttpClient httpClient = new HttpClient() { Timeout = TimeSpan.FromSeconds(5) };
+
+
+ public static void Init() {
+ Path.Combine(ConfigManager.AppDataPath, "FavIcons").EnsureFolderExists();
+ }
+
+ private static string GetIconPath(string domain) {
+ var cleanDomain = domain.RemovePrefix("www.").Replace(".", "_");
+ return Path.Combine(ConfigManager.AppDataPath, "FavIcons\\" + cleanDomain + ".ico");
+ }
+
+ public static async void LoadFavicon(ChromiumWebBrowser browser, bool readCacheOnly) {
+
+ //try {
+ var uri = new Uri(browser.Address);
+ var domain = uri.Host;
+
+ //--------------------------------------------------------------
+ // 1. Check in-mem cache first
+ if (FaviconCache.TryGetValue(domain, out byte[] cachedIcon)) {
+ OnLoaded(browser, cachedIcon);
+ return;
+ }
+
+ //--------------------------------------------------------------
+ // 2. Check on-disk cache second
+
+ var path = GetIconPath(domain);
+ if (File.Exists(path)) {
+ var diskIcon = await File.ReadAllBytesAsync(path);
+ StoreFavicon(domain, diskIcon, false);
+ OnLoaded(browser, diskIcon);
+ return;
+ }
+
+ byte[] iconBitmap = null;
+
+ if (readCacheOnly) return;
+
+ //--------------------------------------------------------------
+ // 3. Try the standard favicon paths first
+ iconBitmap = await TryGetFaviconFromUrl($"{uri.Scheme}://{domain}/favicon.ico");
+ if (iconBitmap == null) {
+ iconBitmap = await TryGetFaviconFromUrl($"{uri.Scheme}://{domain}/favicon.png");
+ }
+ if (iconBitmap != null) {
+ //Console.WriteLine("Favicon loaded from default path.");
+ StoreFavicon(domain, iconBitmap, true);
+ OnLoaded(browser, iconBitmap);
+ return;
+ }
+
+ //--------------------------------------------------------------
+ // 4. Check in-mem cache again
+ if (FaviconCache.TryGetValue(domain, out byte[] cachedIcon2)) {
+ OnLoaded(browser, cachedIcon2);
+ return;
+ }
+
+ //--------------------------------------------------------------
+ // 5. Search for the link tag on the page for the icon path
+ if (browser is null || browser.IsDisposed || browser.Disposing) //because its async..
+ return;
+
+ var result = await browser.EvaluateScriptAsync(FavIconJS);
+ if (result.Success && result.Result is string iconHref && !string.IsNullOrWhiteSpace(iconHref)) {
+ try {
+ var iconUri = new Uri(iconHref, UriKind.RelativeOrAbsolute);
+ if (!iconUri.IsAbsoluteUri) {
+ iconUri = new Uri(uri, iconUri);
+ }
+
+ iconBitmap = await TryGetFaviconFromUrl(iconUri.ToString());
+ if (iconBitmap != null) {
+ //Console.WriteLine("Favicon loaded from tag.");
+ StoreFavicon(domain, iconBitmap, true);
+ OnLoaded(browser, iconBitmap);
+ return;
+ }
+ }
+ catch (Exception ex) {
+ //Console.WriteLine($"Error processing link favicon: {ex.Message}");
+ }
+ }
+
+
+ // NOT FOUND!
+ //if you dont do this, there is residue favicon from previous Website.
+ //iconBitmap = NotFound_favico;
+ iconBitmap = null;
+ OnLoaded(browser, iconBitmap);
+ return;
+
+ //Console.WriteLine("No favicon could be retrieved.");
+ /*}
+ catch (Exception ex) {
+ Console.WriteLine($"Error in favicon retrieval process: {ex.Message}");
+ }*/
+ }
+
+ ///
+ /// Helper method to download the favicon bitmap from any favicon URL.
+ ///
+ private static async Task TryGetFaviconFromUrl(string iconUrl) {
+ try {
+ var response = await httpClient.GetAsync(iconUrl);
+
+ if (!response.Content.Headers.ContentType?.MediaType.StartsWith("image") ?? false) {
+ // non image returned!!
+ return null;
+ }
+
+ if (response.IsSuccessStatusCode) {
+ using (var stream = await response.Content.ReadAsStreamAsync()) {
+ try {
+ // Create memory stream to avoid stream disposal issues
+ using (var memoryStream = new MemoryStream()) {
+ await stream.CopyToAsync(memoryStream);
+ memoryStream.Position = 0;
+ return memoryStream.ToArray();
+ }
+ }
+ catch (ArgumentException) {
+ // Invalid image format - silently fail
+ return null;
+ }
+ }
+ }
+ }
+ catch (Exception ex) {
+ //Console.WriteLine($"HTTP error for {iconUrl}: {ex.Message}");
+ }
+ return null;
+ }
+
+ ///
+ /// Helper method to safely store favicon in cache, using thread-safe code to prevent GDI errors.
+ ///
+ private static void StoreFavicon(string domain, byte[] icon, bool saveToDisk) {
+ if (icon != null) {
+ FaviconCache[domain] = icon;
+ if (saveToDisk) {
+ File.WriteAllBytesAsync(GetIconPath(domain), icon);
+ }
+ }
+ }
+
+
+ ///
+ /// JS script to search for HTML `link` tags on the loaded webpage, in order of preference.
+ ///
+ private static string FavIconJS = @"
+ (function() {
+ // Order of preference for rel attributes (most common first)
+ var relPreference = ['icon', 'shortcut icon', 'apple-touch-icon', 'apple-touch-icon-precomposed'];
+ var links = document.getElementsByTagName('link');
+
+ // First pass: try to find icons in preference order
+ for (var p = 0; p < relPreference.length; p++) {
+ var preferredRel = relPreference[p];
+ for (var i = 0; i < links.length; i++) {
+ var rel = links[i].rel.toLowerCase();
+ if (rel === preferredRel && links[i].href) {
+ var iconUrl = links[i].href;
+ if (iconUrl.indexOf('.svg') == -1){
+ return iconUrl;
+ }
+ }
+ }
+ }
+
+ // Second pass: any icon-like rel as a fallback
+ for (var i = 0; i < links.length; i++) {
+ var rel = links[i].rel.toLowerCase();
+ if ((rel.indexOf('icon') !== -1) && links[i].href) {
+ var iconUrl = links[i].href;
+ if (iconUrl.indexOf('.svg') == -1){
+ return iconUrl;
+ }
+ }
+ }
+
+ return null;
+ })()
+ ";
+
+ }
+
+ public static class ImageExtensions
+ {
+ public static byte[] ToByteArray(this Image image) => ToByteArray(image, ImageFormat.Png);
+
+ public static byte[] ToByteArray(this Image image, ImageFormat format)
+ {
+ using (MemoryStream ms = new MemoryStream())
+ {
+ image.Save(ms, format);
+ return ms.ToArray();
+ }
+ }
+ }
+
+}
diff --git a/src/Managers/HotkeyManager.cs b/src/Managers/HotkeyManager.cs
new file mode 100644
index 0000000..788f200
--- /dev/null
+++ b/src/Managers/HotkeyManager.cs
@@ -0,0 +1,34 @@
+using SharpBrowser.Handlers;
+using System.Windows.Forms;
+
+namespace SharpBrowser.Managers {
+ internal static class HotkeyManager {
+
+ ///
+ /// these hotkeys work when the user is focussed on the .NET form and its controls,
+ /// AND when the user is focussed on the browser (CefSharp portion)
+ ///
+ public static void Init(MainForm form) {
+
+ // browser hotkeys
+ KeyboardHandler.AddHotKey(form, form.CloseActiveTab, Keys.W, true);
+ KeyboardHandler.AddHotKey(form, form.CloseActiveTab, Keys.Escape, true);
+ KeyboardHandler.AddHotKey(form, form.AddBlankTab, Keys.T, true);
+ KeyboardHandler.AddHotKey(form, form.RefreshActiveTab, Keys.F5);
+ KeyboardHandler.AddHotKey(form, form.OpenDeveloperTools, Keys.F12);
+ KeyboardHandler.AddHotKey(form, form.NextTab, Keys.Tab, true);
+ KeyboardHandler.AddHotKey(form, form.PrevTab, Keys.Tab, true, true);
+ KeyboardHandler.AddHotKey(form, form.Print, Keys.P, true);
+ KeyboardHandler.AddHotKey(form, form.PrintToPDF, Keys.P, true, true);
+
+ // search hotkeys
+ KeyboardHandler.AddHotKey(form, form.OpenSearch, Keys.F, true);
+ KeyboardHandler.AddHotKey(form, form.CloseSearch, Keys.Escape);
+ KeyboardHandler.AddHotKey(form, form.StopActiveTab, Keys.Escape);
+ KeyboardHandler.AddHotKey(form, form.ToggleFullscreen, Keys.F11);
+
+
+ }
+
+ }
+}
diff --git a/src/Managers/IconManager.cs b/src/Managers/IconManager.cs
new file mode 100644
index 0000000..6654d97
--- /dev/null
+++ b/src/Managers/IconManager.cs
@@ -0,0 +1,30 @@
+using System.Drawing;
+using System.IO;
+using System.Linq;
+using System.Reflection;
+using System.Windows.Forms;
+
+namespace SharpBrowser.Managers {
+ ///
+ /// embedding the resource using the Visual Studio designer results in a blurry icon.
+ /// so this is the best way to get a non-blurry icon for Windows 8+ apps.
+ ///
+ internal static class IconManager {
+
+ public static Assembly assembly = null;
+
+ public static void Init(Form form) {
+ if (assembly == null) assembly = Assembly.GetAssembly(typeof(MainForm));
+ form.Icon = new Icon(GetResourceStream("sharpbrowser.ico"), new Size(64, 64));
+ }
+
+ public static Stream GetResourceStream(string filename, bool withNamespace = true) {
+ try {
+ return assembly.GetManifestResourceStream("SharpBrowser.Resources." + filename);
+ }
+ catch (System.Exception ex) { }
+ return null;
+ }
+
+ }
+}
diff --git a/src/Model/BrowserHotKey.cs b/src/Model/BrowserHotKey.cs
new file mode 100644
index 0000000..3669f76
--- /dev/null
+++ b/src/Model/BrowserHotKey.cs
@@ -0,0 +1,32 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows.Forms;
+
+namespace SharpBrowser.Model {
+ ///
+ /// POCO for holding hotkey data
+ ///
+ internal class BrowserHotKey {
+
+ public Keys Key;
+ public int KeyCode;
+ public bool Ctrl;
+ public bool Shift;
+ public bool Alt;
+
+ public Action Callback;
+
+ public BrowserHotKey(Action callback, Keys key, bool ctrl = false, bool shift = false, bool alt = false) {
+ Callback = callback;
+ Key = key;
+ KeyCode = (int)key;
+ Ctrl = ctrl;
+ Shift = shift;
+ Alt = alt;
+ }
+
+ }
+}
diff --git a/src/Model/BrowserTab.cs b/src/Model/BrowserTab.cs
new file mode 100644
index 0000000..b00a4d1
--- /dev/null
+++ b/src/Model/BrowserTab.cs
@@ -0,0 +1,28 @@
+using CefSharp.WinForms;
+using SharpBrowser.Controls.BrowserTabStrip;
+using System;
+using System.Drawing;
+
+namespace SharpBrowser.Model {
+ ///
+ /// POCO created for holding data per tab
+ ///
+ internal class BrowserTab {
+
+ public bool IsOpen;
+
+ public string OrigURL;
+ public string CurURL;
+ public string Title;
+
+ public string RefererURL;
+
+ public DateTime DateCreated;
+
+ public BrowserTabPage Tab;
+ public ChromiumWebBrowser Browser;
+
+ public Bitmap FavIcon;
+
+ }
+}
diff --git a/src/Program.cs b/src/Program.cs
index 3ab00f6..eb19f8c 100644
--- a/src/Program.cs
+++ b/src/Program.cs
@@ -13,9 +13,19 @@ static class Program
[STAThread]
static void Main()
{
+
+ // ***this line is added***
+ if (Environment.OSVersion.Version.Major >= 6)
+ SetProcessDPIAware();
+
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new MainForm());
}
+
+ // ***also dllimport of that function***
+ [System.Runtime.InteropServices.DllImport("user32.dll")]
+ private static extern bool SetProcessDPIAware();
+
}
}
diff --git a/src/Properties/Resources.Designer.cs b/src/Properties/Resources.Designer.cs
index a5fc914..9015782 100644
--- a/src/Properties/Resources.Designer.cs
+++ b/src/Properties/Resources.Designer.cs
@@ -10,8 +10,9 @@
namespace SharpBrowser.Properties {
using System;
-
-
+ using System.Drawing;
+
+
///
/// A strongly-typed resource class, for looking up localized strings, etc.
///
@@ -19,7 +20,7 @@ namespace SharpBrowser.Properties {
// class via a tool like ResGen or Visual Studio.
// To add or remove a member, edit your .ResX file then rerun ResGen
// with the /str option, or rebuild your VS project.
- [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "15.0.0.0")]
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
internal class Resources {
@@ -31,7 +32,8 @@ internal class Resources {
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
internal Resources() {
}
-
+
+
///
/// Returns the cached ResourceManager instance used by this class.
///
diff --git a/src/Properties/Settings.Designer.cs b/src/Properties/Settings.Designer.cs
index 8ab98d6..e06ea3a 100644
--- a/src/Properties/Settings.Designer.cs
+++ b/src/Properties/Settings.Designer.cs
@@ -12,7 +12,7 @@ namespace SharpBrowser.Properties {
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
- [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "15.9.0.0")]
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "17.0.3.0")]
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
diff --git a/src/SharpBrowser.csproj b/src/SharpBrowser.csproj
index 9e2ec84..31b7eca 100644
--- a/src/SharpBrowser.csproj
+++ b/src/SharpBrowser.csproj
@@ -1,152 +1,46 @@
-
-
-
-
-
-
-
+
- Debug
- AnyCPU
- {703472B8-B275-4F3F-95B6-426036F8462E}
+ net8.0-windowsWinExe
- Properties
- SharpBrowser
- SharpBrowser
- v4.6
- 512
-
-
-
-
-
-
- x86
- true
- pdbonly
- false
- bin\
- DEBUG;TRACE
- prompt
- 4
- false
-
-
- x86
- pdbonly
- true
+ false
+ false
+ true
+ truebin\
- TRACE
- prompt
- 4
- false
-
-
- true
- bin\
- DEBUG;TRACE
- full
- x86
- prompt
- MinimumRecommendedRules.ruleset
-
-
- bin\
- TRACE
- true
- pdbonly
- x86
- promptMinimumRecommendedRules.ruleset
+ x64Resources\sharpbrowser.icoSharpBrowser.Program
+ app.manifest
-
-
- True
- True
- Settings.settings
-
-
-
-
-
-
-
-
-
-
- Form
+
+ Component
-
- MainForm.cs
+
+ Component
-
-
-
-
-
-
- MainForm.cs
-
-
- ResXFileCodeGenerator
- Resources.Designer.cs
- Designer
-
-
- True
- Resources.resx
- True
+
+ Component
-
- Designer
-
-
-
- SettingsSingleFileGenerator
- Settings.Designer.cs
-
-
-
-
+
+
+
+
+
+
+
+
-
-
-
- bin\TabStrip.dll
-
-
-
-
- This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/src/SharpBrowser.sln b/src/SharpBrowser.sln
index 64054d1..0e97afd 100644
--- a/src/SharpBrowser.sln
+++ b/src/SharpBrowser.sln
@@ -1,28 +1,30 @@
Microsoft Visual Studio Solution File, Format Version 12.00
-# Visual Studio 14
-VisualStudioVersion = 14.0.23107.0
+# Visual Studio Version 17
+VisualStudioVersion = 17.3.32901.215
MinimumVisualStudioVersion = 10.0.40219.1
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SharpBrowser", "SharpBrowser.csproj", "{703472B8-B275-4F3F-95B6-426036F8462E}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SharpBrowser", "SharpBrowser.csproj", "{703472B8-B275-4F3F-95B6-426036F8462E}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{41B061E7-4B20-47D6-8B61-C022FA944C24}"
+ ProjectSection(SolutionItems) = preProject
+ .editorconfig = .editorconfig
+ EndProjectSection
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
- Debug|Any CPU = Debug|Any CPU
- Debug|x86 = Debug|x86
- Release|Any CPU = Release|Any CPU
- Release|x86 = Release|x86
+ Debug|x64 = Debug|x64
+ Release|x64 = Release|x64
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
- {703472B8-B275-4F3F-95B6-426036F8462E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {703472B8-B275-4F3F-95B6-426036F8462E}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {703472B8-B275-4F3F-95B6-426036F8462E}.Debug|x86.ActiveCfg = Debug|x86
- {703472B8-B275-4F3F-95B6-426036F8462E}.Debug|x86.Build.0 = Debug|x86
- {703472B8-B275-4F3F-95B6-426036F8462E}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {703472B8-B275-4F3F-95B6-426036F8462E}.Release|Any CPU.Build.0 = Release|Any CPU
- {703472B8-B275-4F3F-95B6-426036F8462E}.Release|x86.ActiveCfg = Release|x86
- {703472B8-B275-4F3F-95B6-426036F8462E}.Release|x86.Build.0 = Release|x86
+ {703472B8-B275-4F3F-95B6-426036F8462E}.Debug|x64.ActiveCfg = Debug|x64
+ {703472B8-B275-4F3F-95B6-426036F8462E}.Debug|x64.Build.0 = Debug|x64
+ {703472B8-B275-4F3F-95B6-426036F8462E}.Release|x64.ActiveCfg = Release|x64
+ {703472B8-B275-4F3F-95B6-426036F8462E}.Release|x64.Build.0 = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {565C1009-C43D-4D6E-996B-E4069AE8A18B}
+ EndGlobalSection
EndGlobal
diff --git a/src/Utils/ColorUtils.cs b/src/Utils/ColorUtils.cs
new file mode 100644
index 0000000..b618803
--- /dev/null
+++ b/src/Utils/ColorUtils.cs
@@ -0,0 +1,52 @@
+using System;
+using System.Drawing;
+using System.Drawing.Drawing2D;
+
+namespace SharpBrowser.Utils {
+ public static class ColorUtils {
+ ///
+ /// Creates color with corrected brightness.
+ ///
+ /// Color to correct.
+ /// The brightness correction factor. Must be between -1 and 1.
+ /// Negative values produce darker colors.
+ ///
+ /// Corrected structure.
+ ///
+ public static Color ChangeColorBrightness(this Color color, float correctionFactor) {
+ correctionFactor = Math.Clamp(correctionFactor, -1, 1);
+
+ float red = (float)color.R;
+ float green = (float)color.G;
+ float blue = (float)color.B;
+
+ if (correctionFactor < 0) {
+ correctionFactor = 1 + correctionFactor;
+ red *= correctionFactor;
+ green *= correctionFactor;
+ blue *= correctionFactor;
+ }
+ else {
+ red = (255 - red) * correctionFactor + red;
+ green = (255 - green) * correctionFactor + green;
+ blue = (255 - blue) * correctionFactor + blue;
+ }
+
+ return Color.FromArgb(color.A, (int)red, (int)green, (int)blue);
+ }
+
+ ///
+ /// Creates color with corrected brightness.
+ ///
+ /// Color to correct.
+ /// The brightness correction factor. Must be between -1 and 1.
+ /// Negative values produce darker colors.
+ ///
+ /// Corrected structure.
+ ///
+ public static Color ChangeColorBrightness(this Color color, double correctionFactor)
+ => ChangeColorBrightness(color, (float)correctionFactor);
+
+
+ }
+}
\ No newline at end of file
diff --git a/src/Utils/FileIconUtils.cs b/src/Utils/FileIconUtils.cs
index 8d20580..eaf6844 100644
--- a/src/Utils/FileIconUtils.cs
+++ b/src/Utils/FileIconUtils.cs
@@ -7,6 +7,7 @@
using System.Reflection;
using System.Collections.Generic;
using System.IO;
+using System.Linq;
namespace SharpBrowser {
@@ -309,8 +310,9 @@ public static Icon IconFromExtension(string extension,
//gets the name of the file that have the icon.
string IconLocation =
ApplicationKey.OpenSubKey("DefaultIcon").GetValue("").ToString();
- string[] IconPath = IconLocation.Split(',');
+ List IconPath = IconLocation.Split(',').ToList();
+ if (IconPath.Count == 1) IconPath.Add("0");
if (IconPath[1] == null) IconPath[1] = "0";
IntPtr[] Large = new IntPtr[1], Small = new IntPtr[1];
diff --git a/src/Utils/FilePathUtils.cs b/src/Utils/FilePathUtils.cs
new file mode 100644
index 0000000..1706905
--- /dev/null
+++ b/src/Utils/FilePathUtils.cs
@@ -0,0 +1,68 @@
+using System;
+using System.IO;
+
+namespace SharpBrowser.Utils {
+ internal static class FilePathUtils {
+
+ public static bool CheckIfFilePath(this string path) {
+
+ if (path.Length >= 3) {
+ if (path[1] == ':') {
+ if (path[2] == '\\') {
+ if (Char.IsLetter(path[0])) {
+ return true;
+ }
+ }
+ }
+ }
+ return false;
+ }
+
+ public static bool CheckIfFilePath2(this string path) {
+
+ if (path.Length >= 3) {
+ if (path[1] == ':') {
+ if (path[2] == '/') {
+ if (Char.IsLetter(path[0])) {
+ return true;
+ }
+ }
+ }
+ }
+ return false;
+ }
+
+ public static bool SupportedInFilePath(this char c) {
+ return !(c == '?' || c == '\'' || c == '\"' || c == '/' || c == '\\' || c == ';' || c == ':' || c == '&' || c == '*' || c == '<' || c == '>' || c == '|' || c == '{' || c == '}' || c == '[' || c == ']' || c == '(' || c == ')');
+ }
+
+ public static string ChangePathSlash(this string filePath, string slash) {
+ if (slash == "\\") {
+ if (filePath.Contains('/')) {
+ return filePath.Replace("/", "\\");
+ }
+ }
+ if (slash == "/") {
+ if (filePath.Contains('\\')) {
+ return filePath.Replace("\\", "/");
+ }
+ }
+ return filePath;
+ }
+ public static string FileURLToPath(this string url) {
+ return url.RemovePrefix("file:///").ChangePathSlash(@"\").DecodeURLForFilepath();
+ }
+
+ public static bool EnsureFolderExists(this string path) {
+ if (!Directory.Exists(path)) {
+ try {
+ Directory.CreateDirectory(path);
+ return true;
+ }
+ catch (Exception ex) {
+ }
+ }
+ return false;
+ }
+ }
+}
diff --git a/src/Utils/GraphicsUtils.cs b/src/Utils/GraphicsUtils.cs
new file mode 100644
index 0000000..fd167dd
--- /dev/null
+++ b/src/Utils/GraphicsUtils.cs
@@ -0,0 +1,181 @@
+using System;
+using System.Drawing;
+using System.Drawing.Drawing2D;
+
+namespace SharpBrowser.Utils {
+ public static partial class GraphicsUtils {
+ ///
+ /// Fills a Rounded Rectangle with integers.
+ public static void FillRoundRectangle(this Graphics g, Brush brush, RectangleF rect, int radius)
+ => g.FillRoundRectangle(brush, rect.X, rect.Y, rect.Width, rect.Height, radius);
+ ///
+ /// Fills a Rounded Rectangle with integers.
+ public static void FillRoundRectangle(this Graphics g, Brush brush, Rectangle rect, int radius)
+ => g.FillRoundRectangle(brush, rect.X, rect.Y, rect.Width, rect.Height, radius);
+
+ ///
+ /// Fills a Rounded Rectangle with continuous numbers.
+ ///
+ public static void FillRoundRectangle(this Graphics g, Brush brush, float x, float y,
+ float width, float height, int radius) {
+ RectangleF rectangle = new RectangleF(x, y, width, height);
+ GraphicsPath path = rectangle.GetRoundedRect(radius);
+ g.FillPath(brush, path);
+ }
+
+ ///
+ /// Draws a Rounded Rectangle border with integers.
+ ///
+ public static void DrawRoundRectangle(this Graphics g, Pen pen, RectangleF rect, int radius)
+ => g.DrawRoundRectangle(pen, rect.X, rect.Y, rect.Width, rect.Height, radius);
+ ///
+ /// Draws a Rounded Rectangle border with integers.
+ ///
+ public static void DrawRoundRectangle(this Graphics g, Pen pen, Rectangle rect, int radius)
+ => g.DrawRoundRectangle(pen, rect.X, rect.Y, rect.Width, rect.Height, radius);
+
+ ///
+ /// Draws a Rounded Rectangle border with continuous numbers.
+ ///
+ public static void DrawRoundRectangle(this Graphics g, Pen pen, float x, float y,
+ float width, float height, int radius) {
+ RectangleF rectangle = new RectangleF(x, y, width, height);
+ GraphicsPath path = rectangle.GetRoundedRect(radius);
+ g.DrawPath(pen, path);
+ }
+
+ private static GraphicsPath GetRoundedRect(this RectangleF bounds, int radius) {
+ int diameter = radius * 2;
+ Size size = new Size(diameter, diameter);
+ RectangleF arc = new RectangleF(bounds.Location, size);
+ GraphicsPath path = new GraphicsPath();
+
+ if (radius == 0) {
+ path.AddRectangle(bounds);
+ return path;
+ }
+
+ // top left arc
+ path.AddArc(arc, 180, 90);
+
+ // top right arc
+ arc.X = bounds.Right - diameter;
+ path.AddArc(arc, 270, 90);
+
+ // bottom right arc
+ arc.Y = bounds.Bottom - diameter;
+ path.AddArc(arc, 0, 90);
+
+ // bottom left arc
+ arc.X = bounds.Left;
+ path.AddArc(arc, 90, 90);
+
+ path.CloseFigure();
+ return path;
+ }
+
+ public static GraphicsPath CreateTabPath_roundTop(this RectangleF tabRect, float cornerRadius) {
+ GraphicsPath path = new GraphicsPath();
+
+ if (cornerRadius <= 0) {
+ path.AddRectangle(tabRect); // If no corner radius, just a rectangle
+ return path;
+ }
+
+ float diameter = cornerRadius * 2;
+ RectangleF arcRect = new RectangleF(tabRect.Location, new SizeF(diameter, diameter));
+
+ // Top-Left Arc
+ path.AddArc(arcRect, 180, 90);
+
+ // Top Line
+ PointF topRightCornerStart = new PointF(tabRect.Left + cornerRadius, tabRect.Top);
+ PointF topRightCornerEnd = new PointF(tabRect.Right - cornerRadius, tabRect.Top);
+ path.AddLine(topRightCornerStart, topRightCornerEnd);
+
+ // Top-Right Arc
+ arcRect.X = tabRect.Right - diameter;
+ path.AddArc(arcRect, 270, 90);
+
+ // Right Line
+ path.AddLine(new PointF(tabRect.Right, tabRect.Top + cornerRadius), new PointF(tabRect.Right, tabRect.Bottom));
+
+ // Bottom Line
+ path.AddLine(new PointF(tabRect.Right, tabRect.Bottom), new PointF(tabRect.Left, tabRect.Bottom));
+
+ // Left Line - Closing the path
+ path.AddLine(new PointF(tabRect.Left, tabRect.Bottom), new PointF(tabRect.Left, tabRect.Top + cornerRadius));
+
+ path.CloseFigure();
+
+ return path;
+ }
+ public static GraphicsPath CreateTabPath_roundAll(this RectangleF tabRect, float cornerRadius) {
+ GraphicsPath path = new GraphicsPath();
+
+ if (cornerRadius <= 0) {
+ path.AddRectangle(tabRect);
+ return path;
+ }
+
+ float diameter = cornerRadius * 2;
+ RectangleF arcRect = new RectangleF(tabRect.Location, new SizeF(diameter, diameter));
+
+ // Top-Left Arc
+ path.AddArc(arcRect, 180, 90);
+
+ // Top Line
+ PointF topRightCornerStart = new PointF(tabRect.Left + cornerRadius, tabRect.Top);
+ PointF topRightCornerEnd = new PointF(tabRect.Right - cornerRadius, tabRect.Top);
+ path.AddLine(topRightCornerStart, topRightCornerEnd);
+
+ // Top-Right Arc
+ arcRect.X = tabRect.Right - diameter;
+ path.AddArc(arcRect, 270, 90);
+
+ // Right Line
+ path.AddLine(new PointF(tabRect.Right, tabRect.Top + cornerRadius), new PointF(tabRect.Right, tabRect.Bottom - cornerRadius));
+
+ // Bottom-Right Arc (Bottom Round to Out - now Round All)
+ arcRect.Y = tabRect.Bottom - diameter; // Move arcRect to bottom-right corner
+ path.AddArc(arcRect, 0, 90); // Start at 0 degrees (right), sweep 90 degrees clockwise
+
+ // Bottom Line (Not needed, arc goes to bottom-left corner)
+
+ // Bottom-Left Arc (Bottom Round to Out - now Round All)
+ arcRect.X = tabRect.Left; // Move arcRect to bottom-left corner (X is already set to 0)
+ path.AddArc(arcRect, 90, 90); // Start at 90 degrees (bottom), sweep 90 degrees clockwise
+
+ // Left Line - Closing the path
+ path.AddLine(new PointF(tabRect.Left, tabRect.Bottom - cornerRadius), new PointF(tabRect.Left, tabRect.Top + cornerRadius));
+
+
+ path.CloseFigure();
+
+ return path;
+ }
+
+
+ public static GraphicsPath CreateTabPath_Active(Rectangle rect, int radius) {
+ GraphicsPath path = new GraphicsPath();
+ // Ensure radius is not larger than half the width or height
+ radius = Math.Min(radius, Math.Min(rect.Width / 2, rect.Height / 2));
+
+ //// Bottom-left arc
+ path.AddArc(rect.X - radius * 2, rect.Y + rect.Height - radius * 2, radius * 2, radius * 2, 90, -90);
+ //// Top-left arc
+ path.AddArc(rect.X, rect.Y, radius * 2, radius * 2, 180, 90);
+ // Top-right arc
+ path.AddArc(rect.X + rect.Width - radius * 2, rect.Y, radius * 2, radius * 2, 270, 90);
+ // Bottom-right arc
+ path.AddArc(rect.X + rect.Width, rect.Y + rect.Height - radius * 2, radius * 2, radius * 2, -90 * 2, -90);
+
+ //path.CloseFigure(); // Close the path to connect the last and first points
+ return path;
+ }
+ public static GraphicsPath CreateTabPath_Roundtop_RoundBottomOut(this RectangleF tabRect, float cornerRadius)
+ => CreateTabPath_Active(Rectangle.Round(tabRect), (int)cornerRadius);
+
+
+ }
+}
\ No newline at end of file
diff --git a/src/Utils/ImageUtils.cs b/src/Utils/ImageUtils.cs
new file mode 100644
index 0000000..8391651
--- /dev/null
+++ b/src/Utils/ImageUtils.cs
@@ -0,0 +1,56 @@
+using System;
+using System.Drawing;
+using System.Drawing.Drawing2D;
+
+namespace SharpBrowser.Utils {
+ public static class ImageUtils {
+ ///
+ /// btn.BackgroundImage Has no Disabled Effect . wee need lighter
+ ///
+ ///
+ /// 0 to 100
+ ///
+ ///
+ ///
+ ///
+ public static Image Lighter(this Image imgLight, int level, int nRed, int nGreen, int nBlue) {
+ //convert image to graphics object
+ Graphics graphics = Graphics.FromImage(imgLight);
+ int conversion = (5 * (level - 50)); //calculate new alpha value
+ //create mask with blended alpha value and chosen color as pen
+ Pen pLight = new Pen(Color.FromArgb(conversion, nRed, nGreen, nBlue), imgLight.Width * 2);
+ //apply created mask to graphics object
+ graphics.DrawLine(pLight, -1, -1, imgLight.Width, imgLight.Height);
+ //save created graphics object and modify image object by that
+ graphics.Save();
+ graphics.Dispose(); //dispose graphics object
+ return imgLight; //return modified image
+ }
+
+ ///
+ /// recommended defaults level:90, color:Color.white
+ /// 90 level - fade effect is instense,
+ /// 10 level - has nearly no effect;
+ ///
+ ///
+ ///
+ ///
+ ///
+ public static Image Lighter(this Image imgLight, int level, Color col)
+ => imgLight.Lighter(level, col.R, col.G, col.B);
+
+ ///
+ /// recommended defaults level:90, color:Color.white
+ /// 90 level - fade effect is instense,
+ /// 10 level - has nearly no effect;
+ ///
+ ///
+ ///
+ ///
+ ///
+ public static Image Lighter(this Image imgLight, int level = 90) {
+ var col = Color.White;
+ return imgLight.Lighter(level, col.R, col.G, col.B);
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Utils/MiscUtils.cs b/src/Utils/MiscUtils.cs
deleted file mode 100644
index 4a16548..0000000
--- a/src/Utils/MiscUtils.cs
+++ /dev/null
@@ -1,154 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Diagnostics;
-using System.IO;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-using System.Windows.Forms;
-using CefSharp;
-
-namespace SharpBrowser {
- internal static class Utils {
-
- public static bool IsFocussed(TextBox tb) {
- return tb.Focused;
- }
-
- public static void AddHotKey(Form form, Action function, Keys key, bool ctrl = false, bool shift = false, bool alt = false) {
- form.KeyPreview = true;
- form.KeyDown += delegate(object sender, KeyEventArgs e) {
- if (e.IsHotkey(key, ctrl, shift, alt)) {
- function();
- }
- };
- }
-
- public static bool IsFullySelected(TextBox tb) {
- return tb.SelectionLength == tb.TextLength;
- }
- public static bool HasSelection(TextBox tb) {
- return tb.SelectionLength > 0;
- }
-
-
- public static bool CheckIfFilePath(this string path) {
-
- if (path[1] == ':') {
- if (path[2] == '\\') {
- if (Char.IsLetter(path[0])) {
- return true;
- }
- }
- }
- return false;
- }
-
- public static bool CheckIfFilePath2(this string path) {
-
- if (path[1] == ':') {
- if (path[2] == '/') {
- if (Char.IsLetter(path[0])) {
- return true;
- }
- }
- }
- return false;
- }
-
- public static string GetAfter(this string text, string find, int startAt = 0, bool returnAll = false, bool forward = true) {
- if (text == null) { return returnAll ? text : ""; }
- int idx;
- if (!forward) {
- idx = text.LastIndexOf(find, text.Length - startAt, StringComparison.Ordinal);
- } else {
- idx = text.IndexOf(find, startAt, StringComparison.Ordinal);
- }
- if (idx == -1) { return returnAll ? text : ""; }
- idx += find.Length;
- return text.Substring(idx);
- }
-
- public static string GetAfterLast(this string text, string find, bool returnAll = false) {
- int idx = text.LastIndexOf(find, StringComparison.Ordinal);
- if (idx == -1) {
- return returnAll ? text : "";
- }
- idx += find.Length;
- return text.Substring(idx);
- }
-
- public static bool SupportedInFilePath(this char c) {
- return !(c == '?' || c == '\'' || c == '\"' || c == '/' || c == '\\' || c == ';' || c == ':' || c == '&' || c == '*' || c == '<' || c == '>' || c == '|' || c == '{' || c == '}' || c == '[' || c == ']' || c == '(' || c == ')');
- }
-
- public static string ChangePathSlash(this string filePath, string slash) {
- if (slash == "\\") {
- if (filePath.Contains('/')) {
- return filePath.Replace("/", "\\");
- }
- }
- if (slash == "/") {
- if (filePath.Contains('\\')) {
- return filePath.Replace("\\", "/");
- }
- }
- return filePath;
- }
- public static string FileURLToPath(this string url) {
- return url.RemovePrefix("file:///").ChangePathSlash(@"\").DecodeURLForFilepath();
- }
-
- public static bool FileNotExists(this string path) {
- return !File.Exists(path);
- }
-
-
- public static string ConvertToString(this object o) {
- if (o is string) {
- return o as string;
- }
- return null;
- }
- public static bool CheckIfValid(this string text, bool trimAndCheck = false) {
- return text != null && text.Length > 0;
- }
-
- public static void InvokeOnParent(this Control control, MethodInvoker method) {
- Control parent = control.Parent == null ? control : control.Parent;
- if (parent.IsHandleCreated) {
- parent.Invoke(method);
- return;
- }
- }
-
- public static bool IsHotkey(this KeyEventArgs eventData, Keys key, bool ctrl = false, bool shift = false, bool alt = false) {
- return eventData.KeyCode == key && eventData.Control == ctrl && eventData.Shift == shift && eventData.Alt == alt;
- }
-
- public static CefState ToCefState(this bool value) {
- return value ? CefState.Enabled : CefState.Disabled;
- }
- public static bool IsBitmaskOn(this int num, int bitmask) {
- return (num & bitmask) != 0;
- }
-
- public static bool BeginsWith(this string str, string beginsWith, bool caseSensitive = true) {
- if (beginsWith.Length > str.Length) {
- return false;
- }
- if (beginsWith.Length == str.Length) {
- return String.Equals(beginsWith, str, caseSensitive ? StringComparison.Ordinal : StringComparison.OrdinalIgnoreCase);
- }
- return str.LastIndexOf(beginsWith, beginsWith.Length - 1, caseSensitive ? StringComparison.Ordinal : StringComparison.OrdinalIgnoreCase) == 0;
- }
- public static string RemovePrefix(this string str, string prefix, bool caseSensitive = true) {
- if (str.Length >= prefix.Length && str.BeginsWith(prefix, caseSensitive)) {
- return str.Substring(prefix.Length);
- }
- return str;
- }
-
-
- }
-}
diff --git a/src/Utils/StringUtils.cs b/src/Utils/StringUtils.cs
new file mode 100644
index 0000000..560a9e4
--- /dev/null
+++ b/src/Utils/StringUtils.cs
@@ -0,0 +1,71 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace SharpBrowser {
+ internal static class StringUtils {
+ public static string ConvertToString(this object o) {
+ if (o is string) {
+ return o as string;
+ }
+ return null;
+ }
+ public static bool CheckIfValid(this string text, bool trimAndCheck = false) {
+ return text != null && text.Length > 0;
+ }
+ public static bool BeginsWith(this string str, string beginsWith, bool caseSensitive = true) {
+ if (beginsWith.Length > str.Length) {
+ return false;
+ }
+ if (beginsWith.Length == str.Length) {
+ return String.Equals(beginsWith, str, caseSensitive ? StringComparison.Ordinal : StringComparison.OrdinalIgnoreCase);
+ }
+ return str.LastIndexOf(beginsWith, beginsWith.Length - 1, caseSensitive ? StringComparison.Ordinal : StringComparison.OrdinalIgnoreCase) == 0;
+ }
+ public static string RemovePrefix(this string str, string prefix, bool caseSensitive = true) {
+ if (str.Length >= prefix.Length && str.BeginsWith(prefix, caseSensitive)) {
+ return str.Substring(prefix.Length);
+ }
+ return str;
+ }
+ public static string GetAfter(this string text, string find, int startAt = 0, bool returnAll = false, bool forward = true) {
+ if (text == null) { return returnAll ? text : ""; }
+ int idx;
+ if (!forward) {
+ idx = text.LastIndexOf(find, text.Length - startAt, StringComparison.Ordinal);
+ }
+ else {
+ idx = text.IndexOf(find, startAt, StringComparison.Ordinal);
+ }
+ if (idx == -1) { return returnAll ? text : ""; }
+ idx += find.Length;
+ return text.Substring(idx);
+ }
+
+ public static string GetAfterLast(this string text, string find, bool returnAll = false) {
+ int idx = text.LastIndexOf(find, StringComparison.Ordinal);
+ if (idx == -1) {
+ return returnAll ? text : "";
+ }
+ idx += find.Length;
+ return text.Substring(idx);
+ }
+
+ public static string Join(this IList values, string separator) {
+ StringBuilder result = new StringBuilder();
+ var last = values.Count - 1;
+ for (int i = 0; i < values.Count; i++) {
+ var str = values[i];
+ if (str != null) {
+ result.Append(str);
+ }
+ if (i != last) {
+ result.Append(separator);
+ }
+ }
+ return result.ToString();
+ }
+ }
+}
diff --git a/src/Utils/URLUtils.cs b/src/Utils/URLUtils.cs
index 1f42f92..fc8689f 100644
--- a/src/Utils/URLUtils.cs
+++ b/src/Utils/URLUtils.cs
@@ -1,4 +1,6 @@
-using System;
+using SharpBrowser.Config;
+using SharpBrowser.Utils;
+using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
@@ -7,6 +9,25 @@
namespace SharpBrowser {
internal static class URLUtils {
+ public static string CleanURL(string url) {
+ if (url.BeginsWith("about:")) {
+ return "";
+ }
+ url = url.RemovePrefix("http://");
+ url = url.RemovePrefix("https://");
+ url = url.RemovePrefix("file://");
+ url = url.RemovePrefix("/");
+ return url.DecodeURL();
+ }
+ public static bool IsBlank(string url) {
+ if (url == null) return true;
+ return (url == "" || url == "about:blank");
+ }
+ public static bool IsBlankOrSystem(string url) {
+ if (url == null) return true;
+ return (url == "" || url.BeginsWith("about:") || url.BeginsWith("chrome:") || url.BeginsWith(BrowserConfig.InternalScheme + ":"));
+ }
+
public static string PathToURL(this string filePath, string removeBaseDir = null) {
if (!filePath.CheckIfValid()) {
diff --git a/src/Utils/WinFormsUtils.cs b/src/Utils/WinFormsUtils.cs
new file mode 100644
index 0000000..fa6872f
--- /dev/null
+++ b/src/Utils/WinFormsUtils.cs
@@ -0,0 +1,64 @@
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows.Forms;
+using CefSharp;
+
+namespace SharpBrowser {
+ internal static class WinFormsUtils {
+
+ public static bool IsFocussed(TextBox tb) {
+ return tb.Focused;
+ }
+
+ public static void AddHotKey(Form form, Action function, Keys key, bool ctrl = false, bool shift = false, bool alt = false) {
+ form.KeyPreview = true;
+ form.KeyDown += delegate (object sender, KeyEventArgs e) {
+ if (e.IsHotkey(key, ctrl, shift, alt)) {
+ function();
+ }
+ };
+ }
+
+ public static bool IsFullySelected(TextBox tb) {
+ return tb.SelectionLength == tb.TextLength;
+ }
+ public static bool HasSelection(TextBox tb) {
+ return tb.SelectionLength > 0;
+ }
+
+
+ public static bool FileNotExists(this string path) {
+ return !File.Exists(path);
+ }
+
+
+
+ public static void InvokeOnParent(this Control control, MethodInvoker method) {
+ Control parent = control.Parent == null ? control : control.Parent;
+ if (parent.IsHandleCreated) {
+ parent.Invoke(method);
+ return;
+ }
+ }
+
+ public static bool IsHotkey(this KeyEventArgs eventData, Keys key, bool ctrl = false, bool shift = false, bool alt = false) {
+ return eventData.KeyCode == key && eventData.Control == ctrl && eventData.Shift == shift && eventData.Alt == alt;
+ }
+
+ public static CefState ToCefState(this bool value) {
+ return value ? CefState.Enabled : CefState.Disabled;
+ }
+ public static bool IsBitmaskOn(this int num, int bitmask) {
+ return (num & bitmask) != 0;
+ }
+
+
+
+
+ }
+}
\ No newline at end of file
diff --git a/src/app.manifest b/src/app.manifest
new file mode 100644
index 0000000..e8b7c8c
--- /dev/null
+++ b/src/app.manifest
@@ -0,0 +1,79 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ true
+ true
+
+
+
+
+
+
+
+
diff --git a/src/bin/CefSharp.BrowserSubprocess.Core.dll b/src/bin/CefSharp.BrowserSubprocess.Core.dll
deleted file mode 100644
index 395748d..0000000
Binary files a/src/bin/CefSharp.BrowserSubprocess.Core.dll and /dev/null differ
diff --git a/src/bin/CefSharp.BrowserSubprocess.exe b/src/bin/CefSharp.BrowserSubprocess.exe
deleted file mode 100644
index 84b1a1b..0000000
Binary files a/src/bin/CefSharp.BrowserSubprocess.exe and /dev/null differ
diff --git a/src/bin/CefSharp.Core.dll b/src/bin/CefSharp.Core.dll
deleted file mode 100644
index 3723679..0000000
Binary files a/src/bin/CefSharp.Core.dll and /dev/null differ
diff --git a/src/bin/CefSharp.Core.xml b/src/bin/CefSharp.Core.xml
deleted file mode 100644
index e21a3c0..0000000
--- a/src/bin/CefSharp.Core.xml
+++ /dev/null
@@ -1,1392 +0,0 @@
-
-
-
- "CefSharp.Core"
-
-
-
-
-Creates a detailed expection string from a provided Cef V8 exception.
-
- The exception which will be used as base for the message
-
-
-
-Assigns the provided cef_string_t object from the given .NET string.
-
- The cef_string_t that should be updated.
- The .NET string whose value should be used to update cefStr.
-
-
-
-Converts a .NET List of strings to native (unmanaged) format.
-
- The List of strings that should be converted.
- An unmanaged representation of the provided List of strings, or an empty List if the input is a nullptr.
-
-
-
-Converts a .NET string to native (unmanaged) format. Note that this method does not allocate a new copy of the
-
- The string that should be converted.
- An unmanaged representation of the provided string, or an empty string if the input string is a nullptr.
-
-
-
-Converts an unmanaged vector of strings to a (managed) .NET List of strings.
-
- The vector of strings that should be converted.
- A .NET List of strings.
-
-
-
-Converts an unmanaged string to a (managed) .NET string.
-
- The string that should be converted.
- A .NET string.
-
-
-
-Converts an unmanaged string to a (managed) .NET string.
-
- The string that should be converted.
- A .NET string.
-
-
-
-Register the Widevine CDM plugin.
-
-See for more details.
-
- is a directory that contains the Widevine CDM files
- Returns a Task that can be awaited to receive the response.
-
-
-
-Register the Widevine CDM plugin.
-
-The client application is responsible for downloading an appropriate
-platform-specific CDM binary distribution from Google, extracting the
-contents, and building the required directory structure on the local machine.
-The method class can be used
-to implement this functionality in CefSharp. Contact Google via
-https://www.widevine.com/contact.html for details on CDM download.
-
-
-path is a directory that must contain the following files:
- 1. manifest.json file from the CDM binary distribution (see below).
- 2. widevinecdm file from the CDM binary distribution (e.g.
- widevinecdm.dll on Windows).
- 3. widevidecdmadapter file from the CEF binary distribution (e.g.
- widevinecdmadapter.dll on Windows).
-
-If any of these files are missing or if the manifest file has incorrect
-contents the registration will fail and callback will receive an ErrorCode
-value of .
-
-The manifest.json file must contain the following keys:
- A. "os": Supported OS (e.g. "mac", "win" or "linux").
- B. "arch": Supported architecture (e.g. "ia32" or "x64").
- C. "x-cdm-module-versions": Module API version (e.g. "4").
- D. "x-cdm-interface-versions": Interface API version (e.g. "8").
- E. "x-cdm-host-versions": Host API version (e.g. "8").
- F. "version": CDM version (e.g. "1.4.8.903").
- G. "x-cdm-codecs": List of supported codecs (e.g. "vp8,vp9.0,avc1").
-
-A through E are used to verify compatibility with the current Chromium
-version. If the CDM is not compatible the registration will fail and
-callback will receive an ErrorCode value of .
-
-If registration is not supported at the time that Cef.RegisterWidevineCdm() is called then callback
-will receive an ErrorCode value of .
-
- is a directory that contains the Widevine CDM files
- optional callback -
-will be executed asynchronously once registration is complete
-
-
-
-Sets or clears a specific key-value pair from the crash metadata.
-
-
-
-
-Crash reporting is configured using an INI-style config file named
-crash_reporter.cfg. This file must be placed next to
-the main application executable. File contents are as follows:
-
- # Comments start with a hash character and must be on their own line.
-
- [Config]
- ProductName=<Value of the "prod" crash key; defaults to "cef">
- ProductVersion=<Value of the "ver" crash key; defaults to the CEF version>
- AppName=<Windows only; App-specific folder name component for storing crash
- information; default to "CEF">
- ExternalHandler=<Windows only; Name of the external handler exe to use
- instead of re-launching the main exe; default to empty>
- ServerURL=<crash server URL; default to empty>
- RateLimitEnabled=<True if uploads should be rate limited; default to true>
- MaxUploadsPerDay=<Max uploads per 24 hours, used if rate limit is enabled;
- default to 5>
- MaxDatabaseSizeInMb=<Total crash report disk usage greater than this value
- will cause older reports to be deleted; default to 20>
- MaxDatabaseAgeInDays=<Crash reports older than this value will be deleted;
- default to 5>
-
- [CrashKeys]
- my_key1=<small|medium|large>
- my_key2=<small|medium|large>
-
-Config section:
-
-If "ProductName" and/or "ProductVersion" are set then the specified values
-will be included in the crash dump metadata.
-
-If "AppName" is set on Windows then crash report information (metrics,
-database and dumps) will be stored locally on disk under the
-"C:\Users\[CurrentUser]\AppData\Local\[AppName]\User Data" folder.
-
-If "ExternalHandler" is set on Windows then the specified exe will be
-launched as the crashpad-handler instead of re-launching the main process
-exe. The value can be an absolute path or a path relative to the main exe
-directory.
-
-If "ServerURL" is set then crashes will be uploaded as a multi-part POST
-request to the specified URL. Otherwise, reports will only be stored locally
-on disk.
-
-If "RateLimitEnabled" is set to true then crash report uploads will be rate
-limited as follows:
- 1. If "MaxUploadsPerDay" is set to a positive value then at most the
- specified number of crashes will be uploaded in each 24 hour period.
- 2. If crash upload fails due to a network or server error then an
- incremental backoff delay up to a maximum of 24 hours will be applied for
- retries.
- 3. If a backoff delay is applied and "MaxUploadsPerDay" is > 1 then the
- "MaxUploadsPerDay" value will be reduced to 1 until the client is
- restarted. This helps to avoid an upload flood when the network or
- server error is resolved.
-
-If "MaxDatabaseSizeInMb" is set to a positive value then crash report storage
-on disk will be limited to that size in megabytes. For example, on Windows
-each dump is about 600KB so a "MaxDatabaseSizeInMb" value of 20 equates to
-about 34 crash reports stored on disk.
-
-If "MaxDatabaseAgeInDays" is set to a positive value then crash reports older
-than the specified age in days will be deleted.
-
-CrashKeys section:
-
-Any number of crash keys can be specified for use by the application. Crash
-key values will be truncated based on the specified size (small = 63 bytes,
-medium = 252 bytes, large = 1008 bytes). The value of crash keys can be set
-from any thread or process using the Cef.SetCrashKeyValue function. These
-key/value pairs will be sent to the crash server along with the crash dump
-file. Medium and large values will be chunked for submission. For example,
-if your key is named "mykey" then the value will be broken into ordered
-chunks and submitted using keys named "mykey-1", "mykey-2", etc.
-
- Returns true if crash reporting is enabled.
-
-
-
-Helper function (wrapper around the CefColorSetARGB macro) which combines
-the 4 color components into an uint32 for use with BackgroundColor property
-
- Alpha
- Red
- Green
- Blue
- Returns the color.
-
-
-
-Gets the Global Request Context. Make sure to Dispose of this object when finished.
-The earlier possible place to access the IRequestContext is in IBrowserProcessHandler.OnContextInitialized.
-Alternative use the ChromiumWebBrowser BrowserInitialized (OffScreen) or IsBrowserInitializedChanged (WinForms/WPF) events.
-
- Returns the global request context or null if the RequestContext has not been initialized yet.
-
-
-
-Returns true if called on the specified CEF thread.
-
- Returns true if called on the specified thread.
-
-
-
-Call during process startup to enable High-DPI support on Windows 7 or newer.
-Older versions of Windows should be left DPI-unaware because they do not
-support DirectWrite and GDI fonts are kerned very badly.
-
-
-
-
-Unregister an internal plugin. This may be undone the next time RefreshWebPlugins() is called.
-
- Path (directory + file).
-
-
-
-Cause the plugin list to refresh the next time it is accessed regardless of whether it has already been loaded.
-
-
-
-
-Async returns a list containing Plugin Information
-(Wrapper around CefVisitWebPluginInfo)
-
- Returns List of structs.
-
-
-
-Visit web plugin information. Can be called on any thread in the browser process.
-
-
-
-
-Clear all scheme handler factories registered with the global request context.
-Returns false on error. This function may be called on any thread in the browser process.
-Using this function is equivalent to calling Cef.GetGlobalRequestContext().ClearSchemeHandlerFactories().
-
- Returns false on error.
-
-
-
-This method should only be used by advanced users, if you're unsure then use Cef.Shutdown().
-This function should be called on the main application thread to shut down
-the CEF browser process before the application exits. This method simply obtains a lock
-and calls the native CefShutdown method, only IsInitialized is checked. All ChromiumWebBrowser
-instances MUST be Disposed of before calling this method. If calling this method results in a crash
-or hangs then you're likely hanging on to some unmanaged resources or haven't closed all of your browser
-instances
-
-
-
-
-Shuts down CefSharp and the underlying CEF infrastructure. This method is safe to call multiple times; it will only
-shut down CEF on the first call (all subsequent calls will be ignored).
-This method should be called on the main application thread to shut down the CEF browser process before the application exits.
-If you are Using CefSharp.OffScreen then you must call this explicitly before your application exits or it will hang.
-This method must be called on the same thread as Initialize. If you don't call Shutdown explicitly then CefSharp.Wpf and CefSharp.WinForms
-versions will do their best to call Shutdown for you, if your application is having trouble closing then call thus explicitly.
-
-
-
-
- Returns a cookie manager that neither stores nor retrieves cookies. All
-usage of cookies will be blocked including cookies accessed via the network
-(request/response headers), via JavaScript (document.cookie), and via
-CefCookieManager methods. No cookies will be displayed in DevTools. If you
-wish to only block cookies sent via the network use the IRequestHandler
-CanGetCookies and CanSetCookie methods instead.
-
- A blocking cookie manager
-
-
-
-Returns the global cookie manager. By default data will be stored at CefSettings.CachePath if specified or in memory otherwise.
-Using this method is equivalent to calling Cef.GetGlobalRequestContext().GetDefaultCookieManager()
-The earlier possible place to access the ICookieManager is in IBrowserProcessHandler.OnContextInitialized.
-Alternative use the ChromiumWebBrowser BrowserInitialized (OffScreen) or IsBrowserInitializedChanged (WinForms/WPF) events.
-
- A the global cookie manager or null if the RequestContext has not yet been initialized.
-
-
- Remove all entries from the cross-origin access whitelist.
-
-Remove all entries from the cross-origin access whitelist. Returns false if
-the whitelist cannot be accessed.
-
-
-
- Remove entry from cross-origin whitelist
- The origin allowed to be accessed by the target protocol/domain.
- The target protocol allowed to access the source origin.
- The optional target domain allowed to access the source origin.
- If set to true would allow a blah.example.com if the
- was set to example.com
-
-
-Remove an entry from the cross-origin access whitelist. Returns false if
- is invalid or the whitelist cannot be accessed.
-
-
-
- Add an entry to the cross-origin whitelist.
- The origin allowed to be accessed by the target protocol/domain.
- The target protocol allowed to access the source origin.
- The optional target domain allowed to access the source origin.
- If set to true would allow a blah.example.com if the
- was set to example.com
-
- Returns false if is invalid or the whitelist cannot be accessed.
-
-The same-origin policy restricts how scripts hosted from different origins
-(scheme + domain + port) can communicate. By default, scripts can only access
-resources with the same origin. Scripts hosted on the HTTP and HTTPS schemes
-(but no other schemes) can use the "Access-Control-Allow-Origin" header to
-allow cross-origin requests. For example, https://source.example.com can make
-XMLHttpRequest requests on http://target.example.com if the
-http://target.example.com request returns an "Access-Control-Allow-Origin:
-https://source.example.com" response header.
-Scripts in separate frames or iframes and hosted from the same protocol and
-domain suffix can execute cross-origin JavaScript if both pages set the
-document.domain value to the same domain suffix. For example,
-scheme://foo.example.com and scheme://bar.example.com can communicate using
-JavaScript if both domains set document.domain="example.com".
-This method is used to allow access to origins that would otherwise violate
-the same-origin policy. Scripts hosted underneath the fully qualified
- URL (like http://www.example.com) will be allowed access to
-all resources hosted on the specified and .
-If is non-empty and if false only
-exact domain matches will be allowed. If contains a top-
-level domain component (like "example.com") and is
-true sub-domain matches will be allowed. If is empty and
- if true all domains and IP addresses will be
-allowed.
-This method cannot be used to bypass the restrictions on local or display
-isolated schemes. See the comments on for more
-information.
-
-This function may be called on any thread. Returns false if
-is invalid or the whitelist cannot be accessed.
-
-
-
-
-This function should be called from the application entry point function to execute a secondary process.
-It can be used to run secondary processes from the browser client executable (default behavior) or
-from a separate executable specified by the CefSettings.browser_subprocess_path value.
-If called for the browser process (identified by no "type" command-line value) it will return immediately with a value of -1.
-If called for a recognized secondary process it will block until the process should exit and then return the process exit code.
-The |application| parameter may be empty. The |windows_sandbox_info| parameter is only used on Windows and may be NULL (see cef_sandbox_win.h for details).
-
-
-
-
-Perform a single iteration of CEF message loop processing.This function is
-provided for cases where the CEF message loop must be integrated into an
-existing application message loop. Use of this function is not recommended
-for most users; use CefSettings.MultiThreadedMessageLoop if possible (the deault).
-When using this function care must be taken to balance performance
-against excessive CPU usage. It is recommended to enable the
-CefSettings.ExternalMessagePump option when using
-this function so that IBrowserProcessHandler.OnScheduleMessagePumpWork()
-callbacks can facilitate the scheduling process. This function should only be
-called on the main application thread and only if Cef.Initialize() is called
-with a CefSettings.MultiThreadedMessageLoop value of false. This function
-will not block.
-
-
-
-
-Quit the CEF message loop that was started by calling Cef.RunMessageLoop().
-This function should only be called on the main application thread and only
-if Cef.RunMessageLoop() was used.
-
-
-
-
-Run the CEF message loop. Use this function instead of an application-
-provided message loop to get the best balance between performance and CPU
-usage. This function should only be called on the main application thread and
-only if Cef.Initialize() is called with a
-CefSettings.MultiThreadedMessageLoop value of false. This function will
-block until a quit message is received by the system.
-
-
-
-
-Initializes CefSharp with user-provided settings.
-It's important to note that Initialize/Shutdown MUST be called on your main
-applicaiton thread (Typically the UI thead). If you call them on different
-threads, your application will hang. See the documentation for Cef.Shutdown() for more details.
-
- CefSharp configuration settings.
- Check that all relevant dependencies avaliable, throws exception if any are missing
- Implement this interface to provide handler implementations. Null if you don't wish to handle these events
- true if successful; otherwise, false.
-
-
-
-Initializes CefSharp with user-provided settings.
-It's important to note that Initialize/Shutdown MUST be called on your main
-applicaiton thread (Typically the UI thead). If you call them on different
-threads, your application will hang. See the documentation for Cef.Shutdown() for more details.
-
- CefSharp configuration settings.
- Check that all relevant dependencies avaliable, throws exception if any are missing
- The handler for functionality specific to the browser process. Null if you don't wish to handle these events
- true if successful; otherwise, false.
-
-
-
-Initializes CefSharp with user-provided settings.
-It's important to note that Initialize and Shutdown MUST be called on your main
-applicaiton thread (Typically the UI thead). If you call them on different
-threads, your application will hang. See the documentation for Cef.Shutdown() for more details.
-
- CefSharp configuration settings.
- true if successful; otherwise, false.
-
-
-
-Gets a value that indicates the Git Hash for CEF version currently being used.
-
- The Git Commit Hash
-
-
- Gets a value that indicates the Chromium version currently being used.
- The Chromium version.
-
-
- Gets a value that indicates the CEF version currently being used.
- The CEF Version
-
-
- Gets a value that indicates the version of CefSharp currently being used.
- The CefSharp version.
-
-
- Gets a value that indicates whether CefSharp is initialized.
- true if CefSharp is initialized; otherwise, false.
-
-
-
-Method that will be called when CDM registration is complete. |result|
-will be CEF_CDM_REGISTRATION_ERROR_NONE if registration completed
-successfully. Otherwise, |result| and |error_message| will contain
-additional information about why registration failed.
-
-
-
-
-Set command line arguments for best OSR (Offscreen and WPF) Rendering performance
-This will disable WebGL, look at the source to determine which flags best suite
-your requirements.
-
-
-
-
-Set command line argument to disable GPU Acceleration, this will disable WebGL.
-
-
-
-
-Register a new V8 extension with the specified JavaScript extension code
-
- The V8Extension that contains the extension code.
-
-
-
-Registers a custom scheme using the provided settings.
-
- The CefCustomScheme which provides the details about the scheme.
-
-
-
-Background color used for the browser before a document is loaded and when no document color is
-specified. The alpha component must be either fully opaque (0xFF) or fully transparent (0x00).
-If the alpha component is fully opaque then the RGB components will be used as the background
-color. If the alpha component is fully transparent for a WinForms browser then the default value
-of opaque white be used. If the alpha component is fully transparent for a windowless
-(WPF/OffScreen) browser then transparent painting will be enabled.
-
-
-
-
-Comma delimited ordered list of language codes without any whitespace that
-will be used in the "Accept-Language" HTTP header. May be set globally
-using the CefSettings.AcceptLanguageList value. If both values are
-empty then "en-US,en" will be used.
-
-
-
-
-To persist user preferences as a JSON file in the cache path directory set
-this value to true. A CachePath value must also be specified
-to enable this feature. Also configurable using the
-"persist-user-preferences" command-line switch. Can be overridden for
-individual RequestContext instances via the
-RequestContextSettings.PersistUserPreferences value.
-
-
-
-
-To persist session cookies (cookies without an expiry date or validity
-interval) by default when using the global cookie manager set this value to
-true. Session cookies are generally intended to be transient and most
-Web browsers do not persist them. A CachePath value must also be
-specified to enable this feature. Also configurable using the
-"persist-session-cookies" command-line switch. Can be overridden for
-individual RequestContext instances via the
-RequestContextSettings.PersistSessionCookies value.
-
-
-
-
-Set to true (1) to enable windowless (off-screen) rendering support. Do not
-enable this value if the application does not use windowless rendering as
-it may reduce rendering performance on some systems.
-
-
-
-
-Value that will be returned as the User-Agent HTTP header. If empty the
-default User-Agent string will be used. Also configurable using the
-"user-agent" command-line switch.
-
-
-
-
-The number of stack trace frames to capture for uncaught exceptions.
-Specify a positive value to enable the CefRenderProcessHandler::
-OnUncaughtException() callback. Specify 0 (default value) and
-OnUncaughtException() will not be called. Also configurable using the
-"uncaught-exception-stack-size" command-line switch.
-
-
-
-
-Set to a value between 1024 and 65535 to enable remote debugging on the
-specified port. For example, if 8080 is specified the remote debugging URL
-will be http://localhost:8080. CEF can be remotely debugged from any CEF or
-Chrome browser window. Also configurable using the "remote-debugging-port"
-command-line switch.
-
-
-
-
-Value that will be inserted as the product portion of the default
-User-Agent string. If empty the Chromium product version will be used. If
-|userAgent| is specified this value will be ignored. Also configurable
-using the "product-version" command-line switch.
-
-
-
-
-Set to true to disable loading of pack files for resources and locales.
-A resource bundle handler must be provided for the browser and render
-processes via CefApp::GetResourceBundleHandler() if loading of pack files
-is disabled. Also configurable using the "disable-pack-loading" command-
-line switch.
-
-
-
-
-Custom flags that will be used when initializing the V8 JavaScript engine.
-The consequences of using custom flags may not be well tested. Also
-configurable using the "js-flags" command-line switch.
-
-
-
-
-The log severity. Only messages of this severity level or higher will be
-logged. Also configurable using the "log-severity" command-line switch with
-a value of "verbose", "info", "warning", "error", "error-report" or
-"disable".
-
-
-
-
-The directory and file name to use for the debug log. If empty a default
-log file name and location will be used. On Windows and Linux a "debug.log"
-file will be written in the main executable directory.
-Also configurable using the"log-file" command-line switch.
-
-
-
-
-The fully qualified path for the resources directory. If this value is
-empty the cef.pak and/or devtools_resources.pak files must be located in
-the module directory. Also configurable using the "resources-dir-path" command-line
-switch.
-
-
-
-
-The fully qualified path for the locales directory. If this value is empty
-the locales directory must be located in the module directory.
-Also configurable using the "locales-dir-path" command-line switch.
-
-
-
-
-The locale string that will be passed to WebKit. If empty the default
-locale of "en-US" will be used. Also configurable using the "lang"
-command-line switch.
-
-
-
-
-Set to true in order to completely ignore SSL certificate errors.
-This is NOT recommended.
-
-
-
-
-The location where user data such as spell checking dictionary files will
-be stored on disk. If empty then the default platform-specific user data
-directory will be used ("~/.cef_user_data" directory on Linux,
-"~/Library/Application Support/CEF/User Data" directory on Mac OS X,
-"Local Settings\Application Data\CEF\User Data" directory under the user
-profile directory on Windows).
-
-
-
-
-The location where cache data will be stored on disk. If empty then
-browsers will be created in "incognito mode" where in-memory caches are
-used for storage and no data is persisted to disk. HTML5 databases such as
-localStorage will only persist across sessions if a cache path is
-specified. Can be overridden for individual CefRequestContext instances via
-the RequestContextSettings.CachePath value.
-
-
-
-
-The path to a separate executable that will be launched for sub-processes.
-By default the browser process executable is used. See the comments on
-Cef.ExecuteProcess() for details. Also configurable using the
-"browser-subprocess-path" command-line switch. Default is CefSharp.BrowserSubprocess.exe
-
-
-
-
-Set to true to have the browser process message loop run in a separate
-thread. If false than the CefDoMessageLoopWork() function must be
-called from your application message loop. This option is only supported on
-Windows. The default value is true
-
-
-
-
-Set to true to control browser process main (UI) thread message pump
-scheduling via the IBrowserProcessHandler.OnScheduleMessagePumpWork
-callback. This option is recommended for use in combination with the
-Cef.DoMessageLoopWork() function in cases where the CEF message loop must be
-integrated into an existing application message loop (see additional
-comments and warnings on Cef.DoMessageLoopWork). Enabling this option is not
-recommended for most users; leave this option disabled and use either
-MultiThreadedMessageLoop (the default) if possible.
-
-
-
-
-Set to true to enable date-based expiration of built in network security information (i.e. certificate transparency logs,
-HSTS preloading and pinning information). Enabling this option improves network security but may cause HTTPS load failures when
-using CEF binaries built more than 10 weeks in the past. See https://www.certificate-transparency.org/ and
-https://www.chromium.org/hsts for details. Can be set globally using the CefSettings.EnableNetSecurityExpiration value.
-
-
-
-
-Set to true to disable configuration of browser process features using
-standard CEF and Chromium command-line arguments. Configuration can still
-be specified using CEF data structures or by adding to CefCommandLineArgs
-
-
-
-
-Add custom command line argumens to this collection, they will be
-added in OnBeforeCommandLineProcessing.
-
-
-
-
-List of all V8Extensions to be registered using CefRegisterExtension
-in the render process.
-
-
-
-
-Add Customs schemes to this collection
-
-
-
-
-Default Constructor
-
-
-
-
-Initialization settings. Many of these and other settings can also configured
-using command-line switches.
-
-
-
-
-Class representing popup window features.
-
-
-
-
-Load an extension. If extension resources will be read from disk using the default load implementation then rootDirectoy
-should be the absolute path to the extension resources directory and manifestJson should be null.
-If extension resources will be provided by the client (e.g. via IRequestHandler and/or IExtensionHandler) then rootDirectory
-should be a path component unique to the extension (if not absolute this will be internally prefixed with the PK_DIR_RESOURCES path)
-and manifestJson should contain the contents that would otherwise be read from the "manifest.json" file on disk.
-The loaded extension will be accessible in all contexts sharing the same storage (HasExtension returns true).
-However, only the context on which this method was called is considered the loader (DidLoadExtension returns true) and only the
-loader will receive IRequestContextHandler callbacks for the extension. will be
-called on load success or will be called on load failure.
-If the extension specifies a background script via the "background" manifest key then
-will be called to create the background browser. See that method for additional information about background scripts.
-For visible extension views the client application should evaluate the manifest to determine the correct extension URL to load and then pass
-that URL to the IBrowserHost.CreateBrowser* function after the extension has loaded. For example, the client can look for the "browser_action"
-manifest key as documented at https://developer.chrome.com/extensions/browserAction. Extension URLs take the form "chrome-extension:///".
-Browsers that host extensions differ from normal browsers as follows: - Can access chrome.* JavaScript APIs if allowed by the manifest.
-Visit chrome://extensions-support for the list of extension APIs currently supported by CEF. - Main frame navigation to non-extension
-content is blocked.
-- Pinch-zooming is disabled.
-- returns the hosted extension.
-- CefBrowserHost::IsBackgroundHost returns true for background hosts. See https://developer.chrome.com/extensions for extension implementation and usage documentation.
-
- If extension resources will be read from disk using the default load implementation then rootDirectoy
-should be the absolute path to the extension resources directory and manifestJson should be null
- If extension resources will be provided by the client then rootDirectory should be a path component unique to the extension
-and manifestJson should contain the contents that would otherwise be read from the manifest.json file on disk
- handle events related to browser extensions
-
-
-
-Returns true if this context has access to the extension identified by extensionId.
-This may not be the context that was used to load the extension (see DidLoadExtension).
-This method must be called on the CEF UI thread.
-
- extension id
- Returns true if this context has access to the extension identified by extensionId
- Use Cef.UIThreadTaskFactory to execute this method if required,
- and ChromiumWebBrowser.IsBrowserInitializedChanged are both
-executed on the CEF UI thread, so can be called directly.
-When CefSettings.MultiThreadedMessageLoop == false (the default is true) then the main
-application thread will be the CEF UI thread.
-
-
-
-Retrieve the list of all extensions that this context has access to (see HasExtension).
- will be populated with the list of extension ID values.
-This method must be called on the CEF UI thread.
-
- output a list of extensions Ids
- returns true on success otherwise false
- Use Cef.UIThreadTaskFactory to execute this method if required,
- and ChromiumWebBrowser.IsBrowserInitializedChanged are both
-executed on the CEF UI thread, so can be called directly.
-When CefSettings.MultiThreadedMessageLoop == false (the default is true) then the main
-application thread will be the CEF UI thread.
-
-
-
-Returns the extension matching extensionId or null if no matching extension is accessible in this context (see HasExtension).
-This method must be called on the CEF UI thread.
-
- extension Id
- Returns the extension matching extensionId or null if no matching extension is accessible in this context
- Use Cef.UIThreadTaskFactory to execute this method if required,
- and ChromiumWebBrowser.IsBrowserInitializedChanged are both
-executed on the CEF UI thread, so can be called directly.
-When CefSettings.MultiThreadedMessageLoop == false (the default is true) then the main
-application thread will be the CEF UI thread.
-
-
-
-Returns true if this context was used to load the extension identified by extensionId. Other contexts sharing the same storage will also have access to the extension (see HasExtension).
-This method must be called on the CEF UI thread.
-
- Returns true if this context was used to load the extension identified by extensionId
- Use Cef.UIThreadTaskFactory to execute this method if required,
- and ChromiumWebBrowser.IsBrowserInitializedChanged are both
-executed on the CEF UI thread, so can be called directly.
-When CefSettings.MultiThreadedMessageLoop == false (the default is true) then the main
-application thread will be the CEF UI thread.
-
-
-
-Attempts to resolve origin to a list of associated IP addresses using
-cached data. This method must be called on the CEF IO thread. Use
-Cef.IOThreadTaskFactory to execute on that thread.
-
- host name to resolve
- list of resolved IP
-addresses or empty list if no cached data is available.
- Returns on success
-
-
-
-Attempts to resolve origin to a list of associated IP addresses.
-
- host name to resolve
- A task that represents the Resoolve Host operation. The value of the TResult parameter contains ResolveCallbackResult.
-
-
-
-Clears all active and idle connections that Chromium currently has.
-This is only recommended if you have released all other CEF objects but
-don't yet want to call Cef.Shutdown().
-
- If is non-NULL it will be executed on the CEF UI thread after
-completion. This param is optional
-
-
-
-Clears all certificate exceptions that were added as part of handling
-. If you call this it is
-recommended that you also call or you risk not
-being prompted again for server certificates if you reconnect quickly.
-
- If is non-NULL it will be executed on the CEF UI thread after
-completion. This param is optional
-
-
-
-Set the value associated with preference name. If value is null the
-preference will be restored to its default value. If setting the preference
-fails then error will be populated with a detailed description of the
-problem. This method must be called on the CEF UI thread.
-Preferences set via the command-line usually cannot be modified.
-
- preference key
- preference value
- out error
- Returns true if the value is set successfully and false otherwise.
- Use Cef.UIThreadTaskFactory to execute this method if required,
- and ChromiumWebBrowser.IsBrowserInitializedChanged are both
-executed on the CEF UI thread, so can be called directly.
-When CefSettings.MultiThreadedMessageLoop == false (the default is true) then the main
-application thread will be the CEF UI thread.
-
-
-
-Returns true if the preference with the specified name can be modified
-using SetPreference. As one example preferences set via the command-line
-usually cannot be modified. This method must be called on the CEF UI thread.
-
- preference key
- Returns true if the preference with the specified name can be modified
-using SetPreference
- Use Cef.UIThreadTaskFactory to execute this method if required,
- and ChromiumWebBrowser.IsBrowserInitializedChanged are both
-executed on the CEF UI thread, so can be called directly.
-When CefSettings.MultiThreadedMessageLoop == false (the default is true) then the main
-application thread will be the CEF UI thread.
-
-
-
-Returns all preferences as a dictionary. The returned
-object contains a copy of the underlying preference values and
-modifications to the returned object will not modify the underlying
-preference values. This method must be called on the browser process UI
-thread.
-
- If true then
-preferences currently at their default value will be included.
- Preferences (dictionary can have sub dictionaries)
-
-
-
-Returns the value for the preference with the specified name. Returns
-NULL if the preference does not exist. The returned object contains a copy
-of the underlying preference value and modifications to the returned object
-will not modify the underlying preference value. This method must be called
-on the CEF UI thread.
-
- preference name
- Returns the value for the preference with the specified name
- Use Cef.UIThreadTaskFactory to execute this method if required,
- and ChromiumWebBrowser.IsBrowserInitializedChanged are both
-executed on the CEF UI thread, so can be called directly.
-When CefSettings.MultiThreadedMessageLoop == false (the default is true) then the main
-application thread will be the CEF UI thread.
-
-
-
-Returns true if a preference with the specified name exists. This method
-must be called on the CEF UI thread.
-
- name of preference
- bool if the preference exists
- Use Cef.UIThreadTaskFactory to execute this method if required,
- and ChromiumWebBrowser.IsBrowserInitializedChanged are both
-executed on the CEF UI thread, so can be called directly.
-When CefSettings.MultiThreadedMessageLoop == false (the default is true) then the main
-application thread will be the CEF UI thread.
-
-
-
-Tells all renderer processes associated with this context to throw away
-their plugin list cache. If reloadPages is true they will also reload
-all pages with plugins. RequestContextHandler.OnBeforePluginLoad may
-be called to rebuild the plugin list cache.
-
- reload any pages with pluginst
-
-
-
-Returns the cache path for this object. If empty an "incognito mode"
-in-memory cache is being used.
-
-
-
-
-Clear all registered scheme handler factories.
-
- Returns false on error.
-
-
-
-Register a scheme handler factory for the specified schemeName and optional domainName.
-An empty domainName value for a standard scheme will cause the factory to match all domain
-names. The domainName value will be ignored for non-standard schemes. If schemeName is
-a built-in scheme and no handler is returned by factory then the built-in scheme handler
-factory will be called. If schemeName is a custom scheme then you must also implement the
-IApp.OnRegisterCustomSchemes() method in all processes. This function may be called multiple
-times to change or remove the factory that matches the specified schemeName and optional
-domainName.
-
- Scheme Name
- Optional domain name
- Scheme handler factory
- Returns false if an error occurs.
-
-
-
-Returns true if this object is the global context. The global context is
-used by default when creating a browser or URL request with a NULL context
-argument.
-
-
-
-
-Returns the default cookie manager for this object. This will be the global
-cookie manager if this object is the global request context. Otherwise,
-this will be the default cookie manager used when this request context does
-not receive a value via IRequestContextHandler.GetCookieManager().
-
- If callback is non-NULL it will be executed asnychronously on the CEF IO thread
-after the manager's storage has been initialized.
- Returns the default cookie manager for this object
-
-
-
-Returns true if this object is sharing the same storage as the specified context.
-
- context to compare
- Returns true if same storage
-
-
-
-Returns true if this object is pointing to the same context object.
-
- context to compare
- Returns true if the same
-
-
-
-Creates a new context object that shares storage with other and uses an
-optional handler.
-
- shares storage with this RequestContext
- optional requestContext handler
- Returns a nre RequestContext
-
-
-Creates a new context object that shares storage with | other | and uses an optional | handler | .
-
-
-
-A request context provides request handling for a set of related browser objects.
-A request context is specified when creating a new browser object via the CefBrowserHost
-static factory methods. Browser objects with different request contexts will never be
-hosted in the same render process. Browser objects with the same request context may or
-may not be hosted in the same render process depending on the process model.
-Browser objects created indirectly via the JavaScript window.open function or targeted
-links will share the same render process and the same request context as the source browser.
-When running in single-process mode there is only a single render process (the main process)
-and so all browsers created in single-process mode will share the same request context.
-This will be the first request context passed into a CefBrowserHost static factory method
-and all other request context objects will be ignored.
-
-
-
-
-Set to true to ignore errors related to invalid SSL certificates.
-Enabling this setting can lead to potential security vulnerabilities like
-"man in the middle" attacks. Applications that load content from the
-internet should not enable this setting. Can be set globally using the
-CefSettings.IgnoreCertificateErrors value. This value will be ignored if
-CachePath matches the CefSettings.cache_path value.
-
-
-
-
-Set to true to enable date-based expiration of built in network security information (i.e. certificate transparency logs,
-HSTS preloading and pinning information). Enabling this option improves network security but may cause HTTPS load failures when
-using CEF binaries built more than 10 weeks in the past. See https://www.certificate-transparency.org/ and
-https://www.chromium.org/hsts for details. Can be set globally using the CefSettings.EnableNetSecurityExpiration value.
-
-
-
-
-Comma delimited ordered list of language codes without any whitespace that
-will be used in the "Accept-Language" HTTP header. Can be set globally
-using the CefSettings.accept_language_list value or overridden on a per-
-browser basis using the BrowserSettings.AcceptLanguageList value. If
-all values are empty then "en-US,en" will be used. This value will be
-ignored if CachePath matches the CefSettings.CachePath value.
-
-
-
-
-The location where cache data will be stored on disk. If empty then
-browsers will be created in "incognito mode" where in-memory caches are
-used for storage and no data is persisted to disk. HTML5 databases such as
-localStorage will only persist across sessions if a cache path is
-specified. To share the global browser cache and related configuration set
-this value to match the CefSettings.CachePath value.
-
-
-
-
-To persist user preferences as a JSON file in the cache path directory set
-this value to true. Can be set globally using the
-CefSettings.PersistUserPreferences value. This value will be ignored if
-CachePath is empty or if it matches the CefSettings.CachePath value.
-
-
-
-
-To persist session cookies (cookies without an expiry date or validity
-interval) by default when using the global cookie manager set this value to
-true. Session cookies are generally intended to be transient and most
-Web browsers do not persist them. Can be set globally using the
-CefSettings.PersistSessionCookies value. This value will be ignored if
-CachePath is empty or if it matches the CefSettings.CachePath value.
-
-
-
-
-Default constructor
-
-
-
-
-RequestContextSettings
-
-
-
-
-Gets a value indicating if the browser settings has been disposed.
-
-
-
-
-The maximum rate in frames per second (fps) that CefRenderHandler::OnPaint
-will be called for a windowless browser. The actual fps may be lower if
-the browser cannot generate frames at the requested rate. The minimum
-value is 1 and the maximum value is 60 (default 30). This value can also be
-changed dynamically via IBrowserHost.SetWindowlessFrameRate.
-
-
-
-
-Comma delimited ordered list of language codes without any whitespace that
-will be used in the "Accept-Language" HTTP header. May be overridden on a
-per-browser basis using the CefBrowserSettings.AcceptLanguageList value.
-If both values are empty then "en-US,en" will be used. Can be overridden
-for individual RequestContext instances via the
-RequestContextSettings.AcceptLanguageList value.
-
-
-
-
-Background color used for the browser before a document is loaded and when no document color
-is specified. The alpha component must be either fully opaque (0xFF) or fully transparent (0x00).
-If the alpha component is fully opaque then the RGB components will be used as the background
-color. If the alpha component is fully transparent for a WinForms browser then the
-CefSettings.BackgroundColor value will be used. If the alpha component is fully transparent
-for a windowless (WPF/OffScreen) browser then transparent painting will be enabled.
-
-
-
-
-Controls whether WebGL can be used. Note that WebGL requires hardware
-support and may not work on all systems even when enabled. Also
-configurable using the "disable-webgl" command-line switch.
-
-
-
-
-Controls whether the application cache can be used. Also configurable using
-the "disable-application-cache" command-line switch.
-
-
-
-
-Controls whether databases can be used. Also configurable using the
-"disable-databases" command-line switch.
-
-
-
-
-Controls whether local storage can be used. Also configurable using the
-"disable-local-storage" command-line switch.
-
-
-
-
-Controls whether the tab key can advance focus to links. Also configurable
-using the "disable-tab-to-links" command-line switch.
-
-
-
-
-Controls whether text areas can be resized. Also configurable using the
-"disable-text-area-resize" command-line switch.
-
-
-
-
-Controls whether standalone images will be shrunk to fit the page. Also
-configurable using the "image-shrink-standalone-to-fit" command-line
-switch.
-
-
-
-
-Controls whether image URLs will be loaded from the network. A cached image
-will still be rendered if requested. Also configurable using the
-"disable-image-loading" command-line switch.
-
-
-
-
-Controls whether web security restrictions (same-origin policy) will be
-enforced. Disabling this setting is not recommend as it will allow risky
-security behavior such as cross-site scripting (XSS). Also configurable
-using the "disable-web-security" command-line switch.
-
-
-
-
-Controls whether file URLs will have access to other file URLs. Also
-configurable using the "allow-access-from-files" command-line switch.
-
-
-
-
-Controls whether file URLs will have access to all URLs. Also configurable
-using the "allow-universal-access-from-files" command-line switch.
-
-
-
-
-Controls whether any plugins will be loaded. Also configurable using the
-"disable-plugins" command-line switch.
-
-
-
-
-Controls whether DOM pasting is supported in the editor via
-execCommand("paste"). The |javascript_access_clipboard| setting must also
-be enabled. Also configurable using the "disable-javascript-dom-paste"
-command-line switch.
-
-
-
-
-Controls whether JavaScript can access the clipboard. Also configurable
-using the "disable-javascript-access-clipboard" command-line switch.
-
-
-
-
-Controls whether JavaScript can be used to close windows that were not
-opened via JavaScript. JavaScript can still be used to close windows that
-were opened via JavaScript. Also configurable using the
-"disable-javascript-close-windows" command-line switch.
-
-
-
-
-Controls whether JavaScript can be executed. (Used to Enable/Disable javascript)
-Also configurable using the "disable-javascript" command-line switch.
-
-
-
-
-Controls the loading of fonts from remote sources. Also configurable using
-the "disable-remote-fonts" command-line switch.
-
-
-
-
-Default encoding for Web content. If empty "ISO-8859-1" will be used. Also
-configurable using the "default-encoding" command-line switch.
-
-
-
-
-MinimumLogicalFontSize
-
-
-
-
-MinimumFontSize
-
-
-
-
-DefaultFixedFontSize
-
-
-
-
-DefaultFontSize
-
-
-
-
-FantasyFontFamily
-
-
-
-
-CursiveFontFamily
-
-
-
-
-SansSerifFontFamily
-
-
-
-
-SerifFontFamily
-
-
-
-
-FixedFontFamily
-
-
-
-
-StandardFontFamily
-
-
-
-
-Default Constructor
-
-
-
-
-Internal Constructor
-
-
-
-
-Browser initialization settings. Specify NULL or 0 to get the recommended
-default values. The consequences of using custom values may not be well
-tested. Many of these and other settings can also configured using command-
-line switches.
-
-
-
-
-Get the image hotspot (drag start location relative to image dimensions).
-
-
-
-
-Get the image representation of drag data.
-May return NULL if no image representation is available.
-
-
-
-
-Returns the image width in density independent pixel(DIP) units.
-
-
-
-
-Removes the representation for scaleFactor.
-
-
- true for success
-
-
-
-Returns true if this Image and that Image share the same underlying storage.
-
- image to compare
- returns true if share same underlying storage
-
-
-
-Returns true if this Image is empty.
-
-
-
-
-
-Returns true if this image contains a representation for scaleFactor.
-
-
-
-
-
-
-Returns the image height in density independent pixel(DIP) units.
-
-
-
-
-Returns information for the representation that most closely matches scaleFactor.
-
- scale factor
- actual scale factor
- pixel width
- pixel height
- return if information found for scale factor
-
-
-
-Returns the PNG representation that most closely matches scaleFactor.
-
- scale factor
- is the PNG transparent
- pixel width
- pixel height
- A stream represending the PNG or null.
-
-
-
-Returns the JPEG representation that most closely matches scaleFactor.
-
- scale factor
- image quality
- pixel width
- pixel height
- A stream representing the JPEG or null.
-
-
-
-Returns the bitmap representation that most closely matches scaleFactor.
-
- scale factor
- color type
- alpha type
- pixel width
- pixel height
- A stream represending the bitmap or null.
-
-
-
-Load the request represented by the |request| object.
-
-
-
-
\ No newline at end of file
diff --git a/src/bin/CefSharp.WinForms.XML b/src/bin/CefSharp.WinForms.XML
deleted file mode 100644
index 2479a0f..0000000
--- a/src/bin/CefSharp.WinForms.XML
+++ /dev/null
@@ -1,742 +0,0 @@
-
-
-
- CefSharp.WinForms
-
-
-
-
- Initialization settings. Many of these and other settings can also configured
- using command-line switches.
-
-
-
-
- ChromiumWebBrowser Control Designer
-
-
-
-
- Receives a call when the control that the designer is managing has painted its surface so the designer can paint any additional adornments on top of the control.
-
- args
-
-
-
- Adjusts the set of properties the component exposes through a TypeDescriptor.
-
- properties
-
-
-
- Default implementation of
- for the WinForms implementation
-
-
-
-
-
- Called when the browser component has received focus.
-
- the ChromiumWebBrowser control
- the browser object
- Try to avoid needing to override this logic in a subclass. The implementation in
- DefaultFocusHandler relies on very detailed behavior of how WinForms and
- Windows interact during window activation.
-
-
-
- Called when the browser component is requesting focus.
-
- the ChromiumWebBrowser control
- the browser object
- Indicates where the focus request is originating from.
- Return false to allow the focus to be set or true to cancel setting the focus.
-
-
-
- Called when the browser component is about to lose focus.
- For instance, if focus was on the last HTML element and the user pressed the TAB key.
-
- the ChromiumWebBrowser control
- the browser object
- Will be true if the browser is giving focus to the next component
- and false if the browser is giving focus to the previous component.
-
-
-
- ControlExtensions.
-
-
-
-
- Executes the Action asynchronously on the UI thread, does not block execution on the calling thread.
-
- the control for which the update is required
- action to be performed on the control
-
-
-
- Activates the specified control.
-
- The control.
- true if XXXX, false otherwise.
-
-
-
- Returns whether the supplied control is the currently
- active control.
-
- the control to check
- true if the control is the currently active control
-
-
-
- Selects the next control.
-
- The control.
- if set to true [next].
-
-
-
- ParentFormMessageInterceptor - hooks into the parent forms
- message loop to incercept messages like WM_MOVE
-
-
-
-
-
-
- Keep track of whether a move is in progress.
-
-
-
-
- Used to determine the coordinates involved in the move
-
-
-
-
- Gets or sets the browser.
-
- The browser.
-
-
-
- Gets or sets the parent form.
-
- The parent form.
-
-
-
- Initializes a new instance of the class.
-
- The browser.
-
-
-
- Call to force refinding of the parent Form.
- (i.e. top level window that owns the ChromiumWebBrowserControl)
-
-
-
-
- Adjust the form to listen to if the ChromiumWebBrowserControl's parent changes.
-
- The ChromiumWebBrowser whose parent has changed.
- The instance containing the event data.
-
-
-
- Handles the event.
-
- The sender.
- The instance containing the event data.
-
-
-
- Handles the event.
-
- The sender.
- The instance containing the event data.
-
-
-
- Invokes the default window procedure associated with this window.
-
- A that is associated with the current Windows message.
-
-
-
- Called when [moving].
-
-
-
-
- Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
-
-
-
-
- Releases unmanaged and - optionally - managed resources.
-
- true to release both managed and unmanaged resources; false to release only unmanaged resources.
-
-
-
- When overridden in a derived class, manages an unhandled thread exception.
-
- An that specifies the unhandled thread exception.
-
-
-
- Class NativeMethods.
-
-
-
-
- The w m_ move
-
-
-
-
- The w m_ moving
-
-
-
-
- The w m_ activate
-
-
-
-
- WinForms specific implementation, has events the
- implementation exposes.
-
-
-
-
-
- Occurs when the browser title changed.
- It's important to note this event is fired on a CEF UI thread, which by default is not the same as your application UI
- thread. It is unwise to block on this thread for any length of time as your browser will become unresponsive and/or hang..
- To access UI elements you'll need to Invoke/Dispatch onto the UI Thread.
-
-
-
-
- Occurs when the browser address changed.
- It's important to note this event is fired on a CEF UI thread, which by default is not the same as your application UI
- thread. It is unwise to block on this thread for any length of time as your browser will become unresponsive and/or hang..
- To access UI elements you'll need to Invoke/Dispatch onto the UI Thread.
-
-
-
-
- ChromiumWebBrowser is the WinForms web browser control
-
-
-
-
-
-
-
- The managed cef browser adapter
-
-
-
-
- The parent form message interceptor
-
-
-
-
- The browser
-
-
-
-
- A flag that indicates whether or not the designer is active
- NOTE: DesignMode becomes false by the time we get to the destructor/dispose so it gets stored here
-
-
-
-
- A flag that indicates whether or not has been called.
-
-
-
-
- Has the underlying Cef Browser been created (slightly different to initliazed in that
- the browser is initialized in an async fashion)
-
-
-
-
- Browser initialization settings
-
-
-
-
- The request context (we deliberately use a private variable so we can throw an exception if
- user attempts to set after browser created)
-
-
-
-
- Set to true while handing an activating WM_ACTIVATE message.
- MUST ONLY be cleared by DefaultFocusHandler.
-
- true if this instance is activating; otherwise, false.
-
-
-
- Gets or sets the browser settings.
-
- The browser settings.
-
-
-
- Gets or sets the request context.
-
- The request context.
-
-
-
- A flag that indicates whether the control is currently loading one or more web pages (true) or not (false).
-
- true if this instance is loading; otherwise, false.
- In the WPF control, this property is implemented as a Dependency Property and fully supports data
- binding.
-
-
-
- The text that will be displayed as a ToolTip
-
- The tooltip text.
-
-
-
- The address (URL) which the browser control is currently displaying.
- Will automatically be updated as the user navigates to another page (e.g. by clicking on a link).
-
- The address.
- In the WPF control, this property is implemented as a Dependency Property and fully supports data
- binding.
-
-
-
- Implement and assign to handle dialog events.
-
- The dialog handler.
-
-
-
- Implement and assign to handle events related to JavaScript Dialogs.
-
- The js dialog handler.
-
-
-
- Implement and assign to handle events related to key press.
-
- The keyboard handler.
-
-
-
- Implement and assign to handle events related to browser requests.
-
- The request handler.
-
-
-
- Implement and assign to handle events related to downloading files.
-
- The download handler.
-
-
-
- Implement and assign to handle events related to browser load status.
-
- The load handler.
-
-
-
- Implement and assign to handle events related to popups.
-
- The life span handler.
-
-
-
- Implement and assign to handle events related to browser display state.
-
- The display handler.
-
-
-
- Implement and assign to handle events related to the browser context menu
-
- The menu handler.
-
-
-
- Implement and assign to handle messages from the render process.
-
- The render process message handler.
-
-
-
- Implement to handle events related to find results.
-
- The find handler.
-
-
-
- The for this ChromiumWebBrowser.
-
- The focus handler.
- If you need customized focus handling behavior for WinForms, the suggested
- best practice would be to inherit from DefaultFocusHandler and try to avoid
- needing to override the logic in OnGotFocus. The implementation in
- DefaultFocusHandler relies on very detailed behavior of how WinForms and
- Windows interact during window activation.
-
-
-
- Implement and assign to handle events related to dragging.
-
- The drag handler.
-
-
-
- Implement and control the loading of resources
-
- The resource handler factory.
-
-
-
- Event handler that will get called when the resource load for a navigation fails or is canceled.
- It's important to note this event is fired on a CEF UI thread, which by default is not the same as your application UI
- thread. It is unwise to block on this thread for any length of time as your browser will become unresponsive and/or hang..
- To access UI elements you'll need to Invoke/Dispatch onto the UI Thread.
-
-
-
-
- Event handler that will get called when the browser begins loading a frame. Multiple frames may be loading at the same
- time. Sub-frames may start or continue loading after the main frame load has ended. This method may not be called for a
- particular frame if the load request for that frame fails. For notification of overall browser load status use
- OnLoadingStateChange instead.
- It's important to note this event is fired on a CEF UI thread, which by default is not the same as your application UI
- thread. It is unwise to block on this thread for any length of time as your browser will become unresponsive and/or hang..
- To access UI elements you'll need to Invoke/Dispatch onto the UI Thread.
-
- Whilst this may seem like a logical place to execute js, it's called before the DOM has been loaded, implement
- as it's called when the underlying V8Context is created
-
-
-
-
- Event handler that will get called when the browser is done loading a frame. Multiple frames may be loading at the same
- time. Sub-frames may start or continue loading after the main frame load has ended. This method will always be called
- for all frames irrespective of whether the request completes successfully.
- It's important to note this event is fired on a CEF UI thread, which by default is not the same as your application UI
- thread. It is unwise to block on this thread for any length of time as your browser will become unresponsive and/or hang..
- To access UI elements you'll need to Invoke/Dispatch onto the UI Thread.
-
-
-
-
- Event handler that will get called when the Loading state has changed.
- This event will be fired twice. Once when loading is initiated either programmatically or
- by user action, and once when loading is terminated due to completion, cancellation of failure.
- It's important to note this event is fired on a CEF UI thread, which by default is not the same as your application UI
- thread. It is unwise to block on this thread for any length of time as your browser will become unresponsive and/or hang..
- To access UI elements you'll need to Invoke/Dispatch onto the UI Thread.
-
-
-
-
- Event handler for receiving Javascript console messages being sent from web pages.
- It's important to note this event is fired on a CEF UI thread, which by default is not the same as your application UI
- thread. It is unwise to block on this thread for any length of time as your browser will become unresponsive and/or hang..
- To access UI elements you'll need to Invoke/Dispatch onto the UI Thread.
- (The exception to this is when your running with settings.MultiThreadedMessageLoop = false, then they'll be the same thread).
-
-
-
-
- Event handler for changes to the status message.
- It's important to note this event is fired on a CEF UI thread, which by default is not the same as your application UI
- thread. It is unwise to block on this thread for any length of time as your browser will become unresponsive and/or hang.
- To access UI elements you'll need to Invoke/Dispatch onto the UI Thread.
- (The exception to this is when your running with settings.MultiThreadedMessageLoop = false, then they'll be the same thread).
-
-
-
-
- Occurs when the browser address changed.
- It's important to note this event is fired on a CEF UI thread, which by default is not the same as your application UI
- thread. It is unwise to block on this thread for any length of time as your browser will become unresponsive and/or hang..
- To access UI elements you'll need to Invoke/Dispatch onto the UI Thread.
-
-
-
-
- Occurs when the browser title changed.
- It's important to note this event is fired on a CEF UI thread, which by default is not the same as your application UI
- thread. It is unwise to block on this thread for any length of time as your browser will become unresponsive and/or hang..
- To access UI elements you'll need to Invoke/Dispatch onto the UI Thread.
-
-
-
-
- Event called after the underlying CEF browser instance has been created.
- It's important to note this event is fired on a CEF UI thread, which by default is not the same as your application UI
- thread. It is unwise to block on this thread for any length of time as your browser will become unresponsive and/or hang..
- To access UI elements you'll need to Invoke/Dispatch onto the UI Thread.
-
-
-
-
- A flag that indicates whether the state of the control currently supports the GoForward action (true) or not (false).
-
- true if this instance can go forward; otherwise, false.
- In the WPF control, this property is implemented as a Dependency Property and fully supports data
- binding.
-
-
-
- A flag that indicates whether the state of the control current supports the GoBack action (true) or not (false).
-
- true if this instance can go back; otherwise, false.
- In the WPF control, this property is implemented as a Dependency Property and fully supports data
- binding.
-
-
-
- A flag that indicates whether the WebBrowser is initialized (true) or not (false).
-
- true if this instance is browser initialized; otherwise, false.
- In the WPF control, this property is implemented as a Dependency Property and fully supports data
- binding.
-
-
-
- A flag that indicates if you can execute javascript in the main frame.
- Flag is set to true in IRenderProcessMessageHandler.OnContextCreated.
- and false in IRenderProcessMessageHandler.OnContextReleased
-
-
-
-
- ParentFormMessageInterceptor hooks the Form handle and forwards
- the move/active messages to the browser, the default is true
- and should only be required when using
- set to true.
-
-
-
-
- Initializes static members of the class.
-
-
-
-
- Handles the event.
-
- The sender.
- The instance containing the event data.
-
-
-
- This constructor exists as the WinForms designer requires a parameterless constructor, if you are instantiating
- an instance of this class in code then use the
- constructor overload instead. Using this constructor in code is unsupported and you may experience 's
- when attempting to access some of the properties immediately after instantiation.
-
-
-
-
- Initializes a new instance of the class.
-
- The address.
- Request context that will be used for this browser instance,
- if null the Global Request Context will be used
-
-
-
- Required for designer support - this method cannot be inlined as the designer
- will attempt to load libcef.dll and will subsiquently throw an exception.
- TODO: Still not happy with this method name, need something better
-
-
-
-
- Releases the unmanaged resources used by the and its child controls and optionally releases the managed resources.
-
- true to release both managed and unmanaged resources; false to release only unmanaged resources.
-
-
-
- Required for designer support - this method cannot be inlined as the designer
- will attempt to load libcef.dll and will subsiquently throw an exception.
-
-
-
-
- Required for designer support - this method cannot be inlined as the designer
- will attempt to load libcef.dll and will subsiquently throw an exception.
-
-
-
-
- Loads the specified URL.
-
- The URL to be loaded.
-
-
-
- Registers a Javascript object in this specific browser instance.
-
- The name of the object. (e.g. "foo", if you want the object to be accessible as window.foo).
- The object to be made accessible to Javascript.
- binding options - camelCaseJavascriptNames default to true
- Browser is already initialized. RegisterJsObject must be +
- called before the underlying CEF browser is created.
-
-
-
- Asynchronously registers a Javascript object in this specific browser instance.
- Only methods of the object will be availabe.
-
- The name of the object. (e.g. "foo", if you want the object to be accessible as window.foo).
- The object to be made accessible to Javascript.
- binding options - camelCaseJavascriptNames default to true
- Browser is already initialized. RegisterJsObject must be +
- called before the underlying CEF browser is created.
- The registered methods can only be called in an async way, they will all return immeditaly and the resulting
- object will be a standard javascript Promise object which is usable to wait for completion or failure.
-
-
-
- The javascript object repository, one repository per ChromiumWebBrowser instance.
-
-
-
-
- Raises the event.
-
- An that contains the event data.
-
-
-
- Called after browser created.
-
- The browser.
-
-
-
- Sets the address.
-
- The instance containing the event data.
-
-
-
- Sets the loading state change.
-
- The instance containing the event data.
-
-
-
- Sets the title.
-
- The instance containing the event data.
-
-
-
- Sets the tooltip text.
-
- The tooltip text.
-
-
-
- Handles the event.
-
- The instance containing the event data.
-
-
-
- Handles the event.
-
- The instance containing the event data.
-
-
-
- Handles the event.
-
- The instance containing the event data.
-
-
-
- Handles the event.
-
- The instance containing the event data.
-
-
-
- Handles the event.
-
- The instance containing the event data.
-
-
-
- Gets the browser adapter.
-
- The browser adapter.
-
-
-
- Gets or sets a value indicating whether this instance has parent.
-
- true if this instance has parent; otherwise, false.
-
-
-
- Manually implement Focused because cef does not implement it.
-
- true if focused; otherwise, false.
- This is also how the Microsoft's WebBrowserControl implements the Focused property.
-
-
-
- Raises the event.
-
- An that contains the event data.
-
-
-
- Resizes the browser.
-
-
-
-
- Raises the event.
-
- An that contains the event data.
-
-
-
- Returns the current IBrowser Instance
-
- browser instance or null
-
-
-
- Makes certain keys as Input keys when CefSettings.MultiThreadedMessageLoop = false
-
- key data
- true for a select list of keys otherwise defers to base.IsInputKey
-
-
-
diff --git a/src/bin/CefSharp.WinForms.dll b/src/bin/CefSharp.WinForms.dll
deleted file mode 100644
index 79636c7..0000000
Binary files a/src/bin/CefSharp.WinForms.dll and /dev/null differ
diff --git a/src/bin/CefSharp.XML b/src/bin/CefSharp.XML
deleted file mode 100644
index cd1648f..0000000
--- a/src/bin/CefSharp.XML
+++ /dev/null
@@ -1,9901 +0,0 @@
-
-
-
- CefSharp
-
-
-
-
- Async extensions for different interfaces
-
-
-
-
- Deletes all cookies that matches all the provided parameters asynchronously.
- If both and are empty, all cookies will be deleted.
-
- cookie manager
- The cookie URL. If an empty string is provided, any URL will be matched.
- The name of the cookie. If an empty string is provided, any URL will be matched.
- Returns -1 if a non-empty invalid URL is specified, or if cookies cannot be accessed;
- otherwise, a task that represents the delete operation. The value of the TResult will be the number of cookies that were deleted or -1 if unknown.
-
-
-
- Sets a cookie given a valid URL and explicit user-provided cookie attributes.
- This function expects each attribute to be well-formed. It will check for disallowed
- characters (e.g. the ';' character is disallowed within the cookie value attribute) and will return false without setting
-
- cookie manager
- The cookie URL. If an empty string is provided, any URL will be matched.
- the cookie to be set
- returns false if the cookie cannot be set (e.g. if illegal charecters such as ';' are used);
- otherwise task that represents the set operation. The value of the TResult parameter contains a bool to indicate success.
-
-
-
- Visits all cookies. The returned cookies are sorted by longest path, then by earliest creation date.
-
- cookie manager
- A task that represents the VisitAllCookies operation. The value of the TResult parameter contains a List of cookies
- or null if cookies cannot be accessed.
-
-
-
- Visits a subset of the cookies. The results are filtered by the given url scheme, host, domain and path.
- If is true, HTTP-only cookies will also be included in the results. The returned cookies
- are sorted by longest path, then by earliest creation date.
-
- cookie manager
- The URL to use for filtering a subset of the cookies available.
- A flag that determines whether HTTP-only cookies will be shown in results.
- A task that represents the VisitUrlCookies operation. The value of the TResult parameter contains a List of cookies.
- or null if cookies cannot be accessed.
-
-
-
- Flush the backing store (if any) to disk.
-
- cookieManager instance
- A task that represents the FlushStore operation. Result indicates if the flush completed successfully.
- Will return false if the cookikes cannot be accessed.
-
-
-
- Javascript binding options
-
-
-
-
- Set of options with the default binding
-
-
-
-
- Camel case the javascript names of properties/methods, defaults to true
-
-
-
-
- Model binder used for passing complex classes as params to methods
-
-
-
-
- Interceptor used for intercepting calls to the target object methods. For instance, can be used
- for logging calls (from js) to .net methods.
-
-
-
-
- Default constructor
-
-
-
-
- Callback interface used for asynchronous continuation of authentication requests.
-
-
-
-
- Continue the authentication request.
-
- requested username
- requested password
-
-
-
- Cancel the authentication request.
-
-
-
-
- Gets a value indicating whether the callback has been disposed of.
-
-
-
-
- Callback interface used to asynchronously continue a download.
-
-
-
-
- Call to continue the download.
-
- full file path for the download including the file name
- or leave blank to use the suggested name and the default temp directory
- Set to true if you do wish to show the default "Save As" dialog
-
-
-
- Gets a value indicating whether the callback has been disposed of.
-
-
-
-
- Generic callback interface used for asynchronous continuation.
-
-
-
-
- Continue processing.
-
-
-
-
- Cancel processing.
-
-
-
-
- Gets a value indicating whether the callback has been disposed of.
-
-
-
-
- Generic callback interface used for asynchronous completion.
-
-
-
-
- Method that will be called once the task is complete.
-
-
-
-
- Gets a value indicating whether the callback has been disposed of.
-
-
-
-
- Interface to implement to be notified of asynchronous completion via ICookieManager.DeleteCookies().
- It will be executed asnychronously on the CEF IO thread after the cookie has been deleted
-
-
-
-
- Method that will be called upon completion.
-
- will be the number of cookies that were deleted or -1 if unknown.
-
-
-
- Gets a value indicating whether the callback has been disposed of.
-
-
-
-
- Callback interface used to asynchronously cancel a download.
-
-
-
-
- Call to cancel the download.
-
-
-
-
- Call to pause the download.
-
-
-
-
- Call to resume the download.
-
-
-
-
- Gets a value indicating whether the callback has been disposed of.
-
-
-
-
- Callback interface for asynchronous continuation of file dialog requests.
-
-
-
-
- Continue the file selection.
-
- should be the 0-based index of the value selected from the accept filters
- array passed to
- should be a single value or a list of values depending on the dialog mode.
- An empty value is treated the same as calling Cancel().
-
-
-
- Cancel the file selection.
-
-
-
-
- Gets a value indicating whether the callback has been disposed of.
-
-
-
-
- Callback interface used for asynchronous continuation of .
-
-
-
-
- Continue the request. Read the resource contents from stream.
-
- stream to be used as response.
-
-
-
- Continue the request
-
- data to be used as response
-
-
-
- Cancel the request.
-
-
-
-
- Javascript callback interface
-
-
-
-
- Callback Id
-
-
-
-
- Execute the javascript callback
-
- param array of objects
- JavascriptResponse
-
-
-
- Check to see if the underlying resource are still available to execute the callback
-
-
-
-
- Gets a value indicating whether the callback has been disposed of.
-
-
-
-
- Callback interface used for asynchronous continuation of JavaScript dialog requests.
-
-
-
-
- Continue the Javascript dialog request.
-
- Set to true if the OK button was pressed.
- value should be specified for prompt dialogs.
-
-
-
- Continue the Javascript dialog request.
-
- Set to true if the OK button was pressed.
-
-
-
- Gets a value indicating whether the callback has been disposed of.
-
-
-
-
- Callback interface for . The methods of this interface
- will be called on the CEF UI thread.
-
-
-
-
- Method that will be executed when the PDF printing has completed.
-
- The output path.
- Will be true if the printing completed
- successfully or false otherwise.
-
-
-
- Gets a value indicating whether the callback has been disposed of.
-
-
-
-
- Content Decryption Module (CDM) registration callback used for asynchronous completion.
-
-
-
-
- Method that will be called once CDM registration is complete
-
- The result of the CDM registration process
-
-
-
- Gets a value indicating whether the callback has been disposed of.
-
-
-
-
- Callback interface used for asynchronous continuation of url requests.
-
-
-
-
- Continue the url request.
-
- If is true the request will be continued, otherwise, the request will be canceled.
-
-
-
- Cancel the url request.
-
-
-
-
- Gets a value indicating whether the callback has been disposed of.
-
-
-
-
- Callback interface for
-
-
-
-
- Called after the ResolveHost request has completed.
-
- The result code
- will be the list of resolved IP addresses or
- empty if the resolution failed.
-
-
-
- Gets a value indicating whether the callback has been disposed of.
-
-
-
-
- Callback interface used for continuation of custom context menu display.
-
-
-
-
- Complete context menu display by selecting the specified commandId and eventFlags;
-
- the command Id
- the event flags
-
-
-
- Cancel context menu display.
-
-
-
-
- Gets a value indicating whether the callback has been disposed of.
-
-
-
-
- Callback interface for IBrowserHost.RunFileDialog.
- The methods of this class will be called on the CEF UI thread.
-
-
-
-
- Called asynchronously after the file dialog is dismissed.
-
- is the 0-based index of the value selected from the accept filters array passed to IBrowserHost.RunFileDialog
- will be a single value or a list of values depending on the dialog mode. If the selection was cancelled filePaths will be empty
-
-
-
- Callback interface used to select a client certificate for authentication.
-
-
-
-
- Callback interface used to select a client certificate for authentication.
-
- selected certificate
-
-
-
- Gets a value indicating whether the callback has been disposed of.
-
-
-
-
- Interface to implement to be notified of asynchronous completion via ICookieManager.SetCookie().
- It will be executed asnychronously on the CEF IO thread after the cookie has been set
-
-
-
-
- Method that will be called upon completion.
-
- success will be true if the cookie was set successfully.
-
-
-
- Gets a value indicating whether the callback has been disposed of.
-
-
-
-
- Provides a callback implementation of .
-
-
-
-
- Invalid Number of Cookies
-
-
-
-
- Default constructor
-
-
-
-
- Task used to await this callback
-
-
-
-
- Provides a callback implementation of .
-
-
-
-
- Default constructor
-
-
-
-
- Task used to await this callback
-
-
-
-
- Provides a callback implementation of for use with asynchronous Widevine CDM registration.
-
-
-
-
- Default constructor
-
-
-
-
- Task used to await this callback
-
-
-
-
- Provides a callback implementation of .
-
-
-
-
- Default constructor
-
-
-
-
- Task used to await this callback
-
-
-
-
- Provides a callback implementation of .
-
-
-
-
- Task used to await this callback
-
-
-
-
- Provides a callback implementation of .
-
-
-
-
- Default constructor
-
-
-
-
- Task used to await this callback
-
-
-
-
- Represents the response to an attempt to register the Widevine Content Decryption Module (CDM)
-
-
-
-
- If CDM registration succeeded then value will be , for other values see the enumeration .
-
-
-
-
- Contains an error message containing additional information if is not .
-
-
-
-
- CdmRegistration
-
- error code
- error message
-
-
-
- Default implementation of which represents the CefApp class
-
-
-
-
- Describes how to interpret the alpha component of a pixel.
-
-
-
-
- No transparency. The alpha component is ignored.
-
-
-
-
- Transparency with pre-multiplied alpha component.
-
-
-
-
- Transparency with post-multiplied alpha component.
-
-
-
-
- Value types supported by
-
-
-
-
- Invalid type
-
-
-
-
- Null
-
-
-
-
- Boolean
-
-
-
-
- Integer
-
-
-
-
- Double
-
-
-
-
- String
-
-
-
-
- Binary
-
-
-
-
- Dictionary
-
-
-
-
- List
-
-
-
-
- Describes how to interpret the components of a pixel.
-
-
-
-
- RGBA with 8 bits per pixel (32bits total).
-
-
-
-
- BGRA with 8 bits per pixel (32bits total).
-
-
-
-
- Cursor type values.
-
-
-
-
- "Verb" of a drag-and-drop operation as negotiated between the source and destination.
-
-
-
-
- None
-
-
-
-
- Copy
-
-
-
-
- Link
-
-
-
-
- Generic
-
-
-
-
- Private
-
-
-
-
- Move
-
-
-
-
- Delete
-
-
-
-
- Every drag operation.
-
-
-
-
- Event arguments for the event
-
-
-
-
- The javascript object repository, used to register objects
-
-
-
-
- Name of the object
-
-
-
-
- Was the object already bound. The default is false for the first js call to
- CefSharp.BindObjectAsync, and subsiquently true if already bound in a given context.
-
-
-
-
- Is the object cached
-
-
-
-
- JavascriptBindingCompleteEventArgs
-
- javascript object repository
- object name
- is the object already bound
- is the object cached
-
-
-
- Event arguments for the event
-
-
-
-
- The javascript object repository, used to register objects
-
-
-
-
- Name of the object
-
-
-
-
- Constructor
-
- object repository
- object name
-
-
-
- Event arguments for the event
-
-
-
-
- The javascript object repository, used to register objects
-
-
-
-
- Name of the objects bound
-
-
-
-
- JavascriptBindingMultipleCompleteEventArgs
-
- Javascript object repository
- object names
-
-
-
- FileDialog Flags
-
-
-
-
- Prompt to overwrite if the user selects an existing file with the Save dialog.
-
-
-
-
- Do not display read-only files.
-
-
-
-
- Default implementation of .
- This class provides default implementations of the methods from ,
- therefore providing a convenience base class for any custom request handler.
-
-
-
-
- Called when the browser needs credentials from the user.
-
- The ChromiumWebBrowser control
- the browser object
- The frame object that needs credentials (This will contain the URL that is being requested.)
- indicates whether the host is a proxy server
- hostname
- port number
- realm
- scheme
- Callback interface used for asynchronous continuation of authentication requests.
- Return true to continue the request and call CefAuthCallback::Continue() when the authentication information is available. Return false to cancel the request.
-
-
-
- Called on the CEF IO thread to optionally filter resource response content.
-
- The ChromiumWebBrowser control
- the browser object
- The frame that is being redirected.
- the request object - cannot be modified in this callback
- the response object - cannot be modified in this callback
- Return an IResponseFilter to intercept this response, otherwise return null
-
-
-
- Called before browser navigation.
- If the navigation is allowed and
- will be called. If the navigation is canceled will be called with an ErrorCode
- value of .
-
- the ChromiumWebBrowser control
- the browser object
- The frame the request is coming from
- the request object - cannot be modified in this callback
- The value will be true if the browser navigated via explicit user gesture
- (e.g. clicking a link) or false if it navigated automatically (e.g. via the DomContentLoaded event).
- has the request been redirected
- Return true to cancel the navigation or false to allow the navigation to proceed.
-
-
-
- Called before a resource request is loaded. For async processing return
- and execute or
-
- The ChromiumWebBrowser control
- the browser object
- The frame object
- the request object - can be modified in this callback.
- Callback interface used for asynchronous continuation of url requests.
- To cancel loading of the resource return
- or to allow the resource to load normally. For async
- return
-
-
-
- Called to handle requests for URLs with an invalid SSL certificate.
- Return true and call either
- in this method or at a later time to continue or cancel the request.
- If CefSettings.IgnoreCertificateErrors is set all invalid certificates
- will be accepted without calling this method.
-
- the ChromiumWebBrowser control
- the browser object
- the error code for this invalid certificate
- the url of the request for the invalid certificate
- ssl certificate information
- Callback interface used for asynchronous continuation of url requests.
- If empty the error cannot be recovered from and the request will be canceled automatically.
- Return false to cancel the request immediately. Return true and use to
- execute in an async fashion.
-
-
-
- Called on the UI thread before OnBeforeBrowse in certain limited cases
- where navigating a new or different browser might be desirable. This
- includes user-initiated navigation that might open in a special way (e.g.
- links clicked via middle-click or ctrl + left-click) and certain types of
- cross-origin navigation initiated from the renderer process (e.g.
- navigating the top-level frame to/from a file URL).
-
- the ChromiumWebBrowser control
- the browser object
- The frame object
- target url
- The value indicates where the user intended to navigate the browser based
- on standard Chromium behaviors (e.g. current tab, new tab, etc).
- The value will be true if the browser navigated via explicit user gesture
- (e.g. clicking a link) or false if it navigated automatically (e.g. via the DomContentLoaded event).
- Return true to cancel the navigation or false to allow the navigation
- to proceed in the source browser's top-level frame.
-
-
-
- Called when a plugin has crashed
-
- the ChromiumWebBrowser control
- the browser object
- path of the plugin that crashed
-
-
-
- Called on the UI thread to handle requests for URLs with an unknown protocol component.
- SECURITY WARNING: YOU SHOULD USE THIS METHOD TO ENFORCE RESTRICTIONS BASED ON SCHEME, HOST OR OTHER URL ANALYSIS BEFORE ALLOWING OS EXECUTION.
-
- The ChromiumWebBrowser control
- the browser object
- the request url
- return to true to attempt execution via the registered OS protocol handler, if any. Otherwise return false.
-
-
-
- Called on the CEF IO thread before sending a network request with a "Cookie"
- request header.
-
- The ChromiumWebBrowser control
- the browser object
- The frame object
- the request object - cannot be modified in this callback
- Return true to allow cookies to be included in the network
- request or false to block cookies
-
-
-
- Called on the CEF IO thread when receiving a network request with a
- "Set-Cookie" response header value represented by cookie.
-
- The ChromiumWebBrowser control
- the browser object
- The frame object
- the request object - cannot be modified in this callback
- the cookie object
- Return true to allow the cookie to be stored or false to block the cookie.
-
-
-
- Called when JavaScript requests a specific storage quota size via the webkitStorageInfo.requestQuota function.
- For async processing return true and execute at a later time to
- grant or deny the request or to cancel.
-
- The ChromiumWebBrowser control
- the browser object
- the origin of the page making the request
- is the requested quota size in bytes
- Callback interface used for asynchronous continuation of url requests.
- Return false to cancel the request immediately. Return true to continue the request
- and call either in this method or at a later time to
- grant or deny the request.
-
-
-
- Called when the render process terminates unexpectedly.
-
- The ChromiumWebBrowser control
- the browser object
- indicates how the process terminated.
-
-
-
- Called on the CEF UI thread when the render view associated
- with browser is ready to receive/handle IPC messages in the render
- process.
-
- The ChromiumWebBrowser control
- the browser object
-
-
-
- Called on the CEF IO thread when a resource load has completed.
-
- The ChromiumWebBrowser control
- the browser object
- The frame that is being redirected.
- the request object - cannot be modified in this callback
- the response object - cannot be modified in this callback
- indicates the load completion status
- is the number of response bytes actually read.
-
-
-
- Called on the IO thread when a resource load is redirected. The
- parameter will contain the old URL and other request-related information.
-
- The ChromiumWebBrowser control
- the browser object
- The frame that is being redirected.
- the request object - cannot be modified in this callback
- the response object
- the new URL and can be changed if desired
-
-
-
- Called on the CEF IO thread when a resource response is received.
- To allow the resource to load normally return false.
- To redirect or retry the resource modify request (url, headers or post body) and return true.
- The response object cannot be modified in this callback.
-
- The ChromiumWebBrowser control
- the browser object
- The frame that is being redirected.
- the request object
- the response object - cannot be modified in this callback
-
- To allow the resource to load normally return false.
- To redirect or retry the resource modify request (url, headers or post body) and return true.
-
-
-
-
- Called when the browser needs user to select Client Certificate for authentication requests (eg. PKI authentication).
-
- The ChromiumWebBrowser control
- the browser object
- indicates whether the host is a proxy server
- hostname
- port number
- List of Client certificates for selection
- Callback interface used for asynchronous continuation of client certificate selection for authentication requests.
- Return true to continue the request and call ISelectClientCertificateCallback.Select() with the selected certificate for authentication.
- Return false to use the default behavior where the browser selects the first certificate from the list.
-
-
-
- Flags used to customize the behavior of CefURLRequest.
-
-
-
-
- Default behavior.
-
-
-
-
- If set the cache will be skipped when handling the request.
-
-
-
-
- If set user name, password, and cookies may be sent with the request, and
- cookies may be saved from the response.
-
-
-
-
- If set upload progress events will be generated when a request has a body.
-
-
-
-
- If set the CefURLRequestClient::OnDownloadData method will not be called.
-
-
-
-
- If set 5XX redirect errors will be propagated to the observer instead of
- automatically re-tried. This currently only applies for requests
- originated in the browser process.
-
-
-
-
- Implement this interface to receive accessibility notification when accessibility events have been registered.
- It's important to note that the methods of this interface are called on a CEF UI thread,
- which by default is not the same as your application UI thread.
-
-
-
-
- Called after renderer process sends accessibility location changes to the browser process.
-
- Updated location info.
-
-
-
- Called after renderer process sends accessibility tree changes to the browser process.
-
- Updated tree info.
-
-
-
- Implement this interface to handle events related to browser extensions.
- The methods of this class will be called on the CEF UI thread.
- See for information about extension loading.
-
-
-
-
- Called if the request fails.
-
- error code
-
-
-
- Called if the request succeeds.
-
- is the loaded extension.
-
-
-
- Called after the IExtension.Unload request has completed.
-
- is the unloaded extension
-
-
-
- Called when an extension needs a browser to host a background script specified via the "background" manifest key.
- The browser will have no visible window and cannot be displayed. To allow creation of the browser optionally
- modify newBrowser and settings and return false. To cancel creation of the browser
- (and consequently cancel load of the background script) return true. Successful creation will be indicated by a call to
- ILifeSpanHandler.OnAfterCreated, and IBrowserHost.IsBackgroundHost
- will return true for the resulting browser. See https://developer.chrome.com/extensions/event_pages for more information
- about extension background script usage.
-
- is the extension that is loading the background script
- is an internally generated reference to an HTML page that will be used to
- load the background script via a script src attribute
- browser settings
- To cancel creation of the browser (and consequently cancel load of the background script) return true, otherwise return false.
-
-
-
- Called when an extension API (e.g. chrome.tabs.create) requests creation of a new browser.
- Successful creation will be indicated by a call to .
-
- the source of the API call
- the source of the API call
- may optionally be specified via the windowId property or
- returned via the GetActiveBrowser() callback and provides the default for the new browser
- is the position value optionally specified via the index property
- is the URL that will be loaded in the browser
- is true if the new browser should be active when opened
- optionally modify if you are going to allow creation of the browser
- optionally modify browser settings
- To cancel creation of the browser return true. To allow creation return false and optionally modify windowInfo and settings
-
-
-
- Called when no tabId is specified to an extension API call that accepts a tabId parameter (e.g. chrome.tabs.*).
-
- extension the call originates from
- browser the call originates from
- Incognito browsers should not be considered unless the source extension has incognito
- access enabled, inwhich case this will be true
- Return the browser that will be acted on by the API call or return null to act on .
- The returned browser must share the same IRequestContext as
-
-
-
- Called when the tabId associated with is specified to an extension API call that accepts a tabId
- parameter (e.g. chrome.tabs.*).
-
- extension the call originates from
- browser the call originates from
- Access to incognito browsers should not be allowed unless the source extension has
- incognito access
- enabled, in which case this will be true.
-
- Return true to allow access of false to deny access.
-
-
-
- Called to retrieve an extension resource that would normally be loaded from disk
- (e.g. if a file parameter is specified to chrome.tabs.executeScript).
- Localization substitutions will not be applied to resources handled via this method.
-
- extension the call originates from
- browser the call originates from
- is the requested relative file path.
- callback used to handle custom resource requests
- To handle the resource request return true and execute either synchronously or asynchronously.
- For the default behavior which reads the resource from the extension directory on disk return false
-
-
-
- Implement this interface to provide handler implementations.
- Methods will be called by the process and/or thread indicated.
-
-
-
-
- Return the handler for functionality specific to the browser process.
- This method is called on multiple threads.
-
-
-
-
- Provides an opportunity to register custom schemes. Do not keep a reference to the object.
- This method is called on the main thread for each process and the registered schemes should be the same across all processes.
-
- scheme registra
-
-
-
- Object representing an extension. Methods may be called on any thread unless otherwise indicated.
-
-
-
-
- Returns the unique extension identifier. This is calculated based on the
- extension public key, if available, or on the extension path. See
- https://developer.chrome.com/extensions/manifest/key for details.
-
-
-
-
- Returns the absolute path to the extension directory on disk. This value
- will be prefixed with PK_DIR_RESOURCES if a relative path was passed to
- IRequestContext.LoadExtension.
-
-
-
-
- Returns the extension manifest contents as a CefDictionaryValue object. See
- https://developer.chrome.com/extensions/manifest for details.
-
-
-
-
- Returns true if this object is the same extension as that object.
- Extensions are considered the same if identifier, path and loader context
- match.
-
- extension to compare
- return true if the same extension
-
-
-
- Returns the request context that loaded this extension. Will return NULL
- for internal extensions or if the extension has been unloaded. See the
- CefRequestContext::LoadExtension documentation for more information about
- loader contexts. Must be called on the CEF UI thread.
-
-
-
-
- Returns true if this extension is currently loaded. Must be called on the
- CEF UI thread.
-
-
-
-
- Unload this extension if it is not an internal extension and is currently
- loaded. Will result in a call to IExtensionHandler.OnExtensionUnloaded
- on success.
-
-
-
-
- Manages custom scheme registrations.
-
-
-
-
- Register a custom scheme. This method should not be called for the built-in
- HTTP, HTTPS, FILE, FTP, ABOUT and DATA schemes.
-
- If is true the scheme will be treated as a standard scheme.
- Standard schemes are subject to URL canonicalization and parsing rules as
- defined in the Common Internet Scheme Syntax RFC 1738 Section 3.1 available
- at http://www.ietf.org/rfc/rfc1738.txt
-
- In particular, the syntax for standard scheme URLs must be of the form:
-
- Standard scheme URLs must have a host component that is a fully qualified
- domain name as defined in Section 3.5 of RFC 1034 [13] and Section 2.1 of
- RFC 1123. These URLs will be canonicalized to "scheme://host/path" in the
- simplest case and "scheme://username:password@host:port/path" in the most
- explicit case. For example, "scheme:host/path" and "scheme:///host/path"
- will both be canonicalized to "scheme://host/path". The origin of a
- standard scheme URL is the combination of scheme, host and port (i.e.,
- "scheme://host:port" in the most explicit case).
-
- For non-standard scheme URLs only the "scheme:" component is parsed and
- canonicalized. The remainder of the URL will be passed to the handler
- as-is. For example, "scheme:///some%20text" will remain the same.
- Non-standard scheme URLs cannot be used as a target for form submission.
-
- This function may be called on any thread. It should only be called once
- per unique value. If is already registered or
- if an error occurs this method will return false.
-
- scheme name, e.g. custom
- is this a standard scheme, see above for details
- If true the scheme will be treated with the same security
- rules as those applied to "file" URLs. Normal pages cannot link to or
- access local URLs. Also, by default, local URLs can only perform
- XMLHttpRequest calls to the same URL (origin + path) that originated the
- request. To allow XMLHttpRequest calls from a local URL to other URLs with
- the same origin set the CefSettings.file_access_from_file_urls_allowed
- value to true. To allow XMLHttpRequest calls from a local URL to all
- origins set the CefSettings.UniversalAccessFromFileUrlsAllowed value
- to true.
- If true the scheme can only be displayed from
- other content hosted with the same scheme. For example, pages in other
- origins cannot create iframes or hyperlinks to URLs with the scheme. For
- schemes that must be accessible from other schemes set this value to false,
- set to true, and use CORS "Access-Control-Allow-Origin"
- headers to further restrict access.
- If true the scheme will be treated with the same security rules as those applied to "https" URLs.
- For example, loading this scheme from other secure schemes will not trigger mixed content warnings.
- If true the scheme can be sent CORS requests. This value should be true in most cases where is true.
- If true the scheme can bypass Content-Security-Policy
- (CSP) checks. This value should be false in most cases where is true.
-
-
-
-
- Interface representing CefValue.
-
-
-
-
- Returns the underlying value type.
-
-
- Returns the underlying value type.
-
-
-
-
- Returns the underlying value as type bool.
-
-
- Returns the underlying value as type bool.
-
-
-
-
- Returns the underlying value as type double.
-
-
- Returns the underlying value as type double.
-
-
-
-
- Returns the underlying value as type int.
-
-
- Returns the underlying value as type int.
-
-
-
-
- Returns the underlying value as type string.
-
-
- Returns the underlying value as type string.
-
-
-
-
- Returns the underlying value as type dictionary.
-
-
- Returns the underlying value as type dictionary.
-
-
-
-
- Returns the underlying value as type list.
-
-
- Returns the underlying value as type list.
-
-
-
-
- Returns the underlying value converted to a managed object.
-
-
- Returns the underlying value converted to a managed object.
-
-
-
-
- Container for a single image represented at different scale factors.
- All image representations should be the same size in density independent pixel (DIP) units.
- For example, if the image at scale factor 1.0 is 100x100 pixels then the image at scale factor 2.0 should be 200x200 pixels -- both images will display with a DIP size of 100x100 units.
- The methods of this class must be called on the browser process UI thread.
-
-
-
-
- Returns the bitmap representation that most closely matches scaleFactor.
-
- scale factor
- color type
- alpha type
- pixel width
- pixel height
- A stream represending the bitmap or null.
-
-
-
- Returns the JPEG representation that most closely matches scaleFactor.
-
- scale factor
- image quality
- pixel width
- pixel height
- A stream representing the JPEG or null.
-
-
-
- Returns the PNG representation that most closely matches scaleFactor.
-
- scale factor
- is the PNG transparent
- pixel width
- pixel height
- A stream represending the PNG or null.
-
-
-
- Returns information for the representation that most closely matches scaleFactor.
-
- scale factor
- actual scale factor
- pixel width
- pixel height
- return if information found for scale factor
-
-
-
- Returns the image height in density independent pixel(DIP) units.
-
-
-
-
- Returns true if this image contains a representation for scaleFactor.
-
-
-
-
-
-
- Returns true if this Image is empty.
-
-
-
-
- Returns true if this Image and that Image share the same underlying storage.
-
- image to compare
- returns true if share same underlying storage
-
-
-
- Removes the representation for scaleFactor.
-
-
- true for success
-
-
-
- Returns the image width in density independent pixel(DIP) units.
-
-
-
-
- Javascript object repository, object are registered for binding
- One repository per ChromiumWebBrowser instance
-
-
-
-
- Register an object for binding in Javascript. You can either
- register an object in advance or as part of the
- event that will be called if no object matching object is found in the registry.
- Objects binding is now initiated in Javascript through the CefSharp.BindObjectAsync
- function (returns a Promose).
- For more detailed examples see https://github.com/cefsharp/CefSharp/issues/2246
- The equivilient to RegisterJsObject is isAsync = false
- The equivilient RegisterAsyncJsObject is isAsync = true
-
- object name
- the object that will be bound in javascript
-
- if true the object will be registered for async communication,
- only methods will be exposed and when called from javascript will return a Promise to be awaited.
- This method is newer and recommended for everyone starting out as it is faster and more reliable.
- If false then methods and properties will be registered, this method relies on a WCF service to communicate.
-
- binding options, by default method/property names are camelCased, you can control this
- and other advanced options though this class.
-
-
-
- UnRegister all the currently bound objects from the repository. If you unregister an object that is currently
- bound in JavaScript then the method/property calls will fail.
-
-
-
-
- UnRegister a bound object from the repository. If you unregister an object that is currently
- bound in JavaScript then the method/property calls will fail.
-
- object name
- returns true if the object was successfully unbound otherwise false.
-
-
-
- Has bound objects
-
-
-
-
- Is object bound
-
- name
- true if object with matching name bound
-
-
-
- Event handler is called when an object with a given name is requested for binding and is not yet
- registered with the repository. Use
- to register objects (using
-
-
-
-
- Event handler is triggered when a object has been successfully bound in javascript
-
-
-
-
- Event handler is triggered when multiple objects has been successfully bound in javascript, this event only
- contains the names of objects successfully bound.
-
-
-
-
- ByteArrayResourceHandler is used as a placeholder class which uses native CEF implementations.
- CefStreamReader::CreateForData(); reads the byte array that is passed to a new instance
- of CefStreamResourceHandler
- TODO: Move this class into Handler namespace
-
-
-
-
- Underlying byte array that represents the data
-
-
-
-
- Gets or sets the Mime Type.
-
-
-
-
- Initializes a new instance of the class.
-
- mimeType
- byte array
-
-
-
- Mapping to/from CefTime
-
-
-
-
- Converts a cef
-
- year
- month
- day
- hour
- minute
- second
- millisecond
- DateTime
-
-
-
- Returns epoch (different from 01/01/1970)
-
- datetime
- epoch
-
-
-
- IRenderWebBrowser is an internal interface used by CefSharp for the WPF/Offscreen implementation
- The ChromiumWebBrowser instances implement this interface
-
-
-
-
- Implement to handle events related to accessibility.
-
- The accessibility handler.
-
-
-
- Called to allow the client to return a ScreenInfo object with appropriate values.
- If null is returned then the rectangle from GetViewRect will be used.
- If the rectangle is still empty or invalid popups may not be drawn correctly.
-
- Return null if no screenInfo structure is provided.
-
-
-
- Called to retrieve the view rectangle which is relative to screen coordinates.
-
- Return a ViewRect strict containing the rectangle or null. If the rectangle is
- still empty or invalid popups may not be drawn correctly.
-
-
-
- Called to retrieve the translation from view coordinates to actual screen coordinates.
-
- x
- y
- screen x
- screen y
- Return true if the screen coordinates were provided.
-
-
-
- Called when an element has been rendered to the shared texture handle.
- This method is only called when is set to true
-
- indicates whether the element is the view or the popup widget.
- contains the set of rectangles in pixel coordinates that need to be repainted
- is the handle for a D3D11 Texture2D that can be accessed via ID3D11Device using the OpenSharedResource method.
-
-
-
- Called when an element should be painted. Pixel values passed to this method are scaled relative to view coordinates based on the
- value of returned from .
- Called on the CEF UI Thread
-
- indicates whether the element is the view or the popup widget.
- contains the set of rectangles in pixel coordinates that need to be repainted
- The bitmap will be will be width * height *4 bytes in size and represents a BGRA image with an upper-left origin
- width
- height
-
-
-
- Called when the browser's cursor has changed. .
-
- If type is Custom then customCursorInfo will be populated with the custom cursor information
- cursor type
- custom cursor Information
-
-
-
- Called when the user starts dragging content in the web view. Contextual information about the dragged content is
- supplied by dragData. (|x|, |y|) is the drag start location in screen coordinates. OS APIs that run a system message
- loop may be used within the StartDragging call. Return false to abort the drag operation. Don't call any of
- CefBrowserHost::DragSource*Ended* methods after returning false. Return true to handle the drag operation.
- Call IBrowserHost::DragSourceEndedAt and DragSourceSystemDragEnded either synchronously or asynchronously to inform
- the web view that the drag operation has ended.
-
- drag data
- operation mask
- x coordinate
- y coordinate
- Return false to abort the drag operation.
-
-
-
- Called when the web view wants to update the mouse cursor during a drag & drop operation.
-
- describes the allowed operation (none, move, copy, link).
-
-
-
- Called when the browser wants to show or hide the popup widget.
-
- The popup should be shown if show is true and hidden if show is false.
-
-
-
- Called when the browser wants to move or resize the popup widget.
-
- contains the new location and size in view coordinates.
-
-
-
- Called when the IME composition range has changed.
-
- is the range of characters that have been selected
- is the bounds of each character in view coordinates.
-
-
-
- Simple helper class used for checking/parsing command line arguments
-
-
-
-
- Interface used to break reference cycles in CefSharp.Core C++ code.
- This will ALWAYS be a ManagedCefBrowserAdapter instance.
-
-
-
-
- Interface to convert a JavascriptCallback dto to a callable implementation.
-
-
-
-
- Do an unchecked conversion from IntPtr to int
- so overflow exceptions don't get thrown.
-
- the IntPtr to cast
- a 32-bit signed integer
-
-
-
- Class to store TaskCompletionSources indexed by a unique id.
-
- The type of the result produced by the tasks held.
-
-
-
- Creates a new pending task with a timeout.
-
- The maximum running time of the task.
- The unique id of the newly created pending task and the newly created .
-
-
-
- Gets and removed pending task by id.
-
- Unique id of the pending task.
-
- The associated with the given id.
-
-
-
-
- TaskExtension based on the following
- https://github.com/ChadBurggraf/parallel-extensions-extras/blob/master/Extensions/TaskExtrasExtensions.cs
- https://github.com/ChadBurggraf/parallel-extensions-extras/blob/ec803e58eee28c698e44f55f49c5ad6671b1aa58/Extensions/TaskCompletionSourceExtensions.cs
-
-
-
- Creates a new Task that mirrors the supplied task but that will be canceled after the specified timeout.
- Specifies the type of data contained in the task.
- The task.
- The timeout.
- The new Task that may time out.
-
-
- Attempts to transfer the result of a Task to the TaskCompletionSource.
- Specifies the type of the result.
- The TaskCompletionSource.
- The task whose completion results should be transfered.
- Whether the transfer could be completed.
-
-
- Attempts to transfer the result of a Task to the TaskCompletionSource.
- Specifies the type of the result.
- The TaskCompletionSource.
- The task whose completion results should be transfered.
- Whether the transfer could be completed.
-
-
-
- Set the TaskCompletionSource in an async fashion. This prevents the Task Continuation being executed sync on the same thread
- This is required otherwise contintinuations will happen on CEF UI threads
-
- Generic param
- tcs
- result
-
-
-
- Gets or sets a delegate which is used to invoke the method if the member is a method.
-
-
-
-
- Identifies the for BrowserProcess to RenderProcess communication
-
-
-
-
- Gets or sets the name of the managed property.
-
-
-
-
- Gets or sets the name of the property in the JavaScript runtime.
-
-
-
-
- Params this method expects
-
-
-
-
- Number of Params this function exepects
-
-
-
-
- This maps the registered objects in the browser process
- to the reflection data necessary to update the objects,
- and mapping information to how the object/method/proprerty
- will be exposed to JavaScript.
-
-
-
-
- Identifies the for BrowserProcess to RenderProcess communication
-
-
-
-
- Indicate if this object bound as async
-
-
-
-
- Indicate if JavascriptName is camel case or not
-
-
-
-
- Gets the methods of the .
-
-
-
-
- Gets the properties of the .
-
-
-
-
- Gets or sets the value.
-
-
-
-
- This class manages the registration of objects in the browser
- process to be exposed to JavaScript in the renderer process.
- Registration performs method, parameter, property type analysis
- of the registered objects into meta-data tied to reflection data
- for later use.
-
- This class also is the adaptation layer between the BrowserProcessService
- and the registered objects. This means when the renderer wants to call an
- exposed method, get a property of an object, or
- set a property of an object in the browser process, that this
- class does deals with the previously created meta-data and invokes the correct
- behavior via reflection APIs.
-
- All of the registered objects are tracked via meta-data for the objects
- expressed starting with the JavaScriptObject type.
-
-
-
-
- A hash from assigned object ids to the objects,
- this is done to speed up finding the object in O(1) time
- instead of traversing the JavaScriptRootObject tree.
-
-
-
-
- Has the browser this repository is associated with been initilized (set in OnAfterCreated)
-
-
-
-
- Analyse the object and generate metadata which will
- be used by the browser subprocess to interact with Cef.
- Method is called recursively
-
- Javascript object
- Analyse methods for inclusion in metadata model
- Analyse properties for inclusion in metadata model
- When analysis is done on a property, if true then get it's value for transmission over WCF
- camel case the javascript names of properties/methods
-
-
-
- Gets or sets a delegate which is used to set the property / field value in the managed object.
-
-
-
-
- Gets or sets a delegate which is used to get the property / field value from the managed object.
-
-
-
-
- Identifies the for BrowserProcess to RenderProcess communication
-
-
-
-
- Gets or sets the name of the managed property.
-
-
-
-
- Gets or sets the name of the property in the JavaScript runtime.
-
-
-
-
- Gets or sets if this property represents a complex type
-
-
-
-
- Gets or sets if this property is read-only
-
-
-
-
- Gets or sets the property value
- Only primative types can be stored in this property
-
-
-
-
- Interface implemented by UI control that contains
- a ManagedCefBrowserAdapter instance.
-
-
-
-
- FileResourceHandler is used as a placeholder class which uses native CEF implementations.
- CefStreamReader::CreateForFile is used to create a CefStreamReader instance which is passed to
- a new instance of CefStreamResourceHandler
- (Was previously ResourceHandlerType::File to differentiate, going for a more flexible approach now)
- TODO: Move this class into Handler namespace
-
-
-
-
- Path of the underlying file
-
-
-
-
- Gets or sets the Mime Type.
-
-
-
-
- Initializes a new instance of the class.
-
- mimeType
- filePath
-
-
-
- Load an extension from the given directory. To load a crx file you must unzip it first.
- For further details see
-
- request context
- absolute path to the directory that contains the extension to be loaded.
- handle events related to browser extensions
-
-
-
- Load extension(s) from the given directory. This methods obtains all the sub directories of
- and calls if manifest.json
- is found in the sub folder. To load crx file(s) you must unzip them first.
- For further details see
-
- request context
- absolute path to the directory that contains the extension(s) to be loaded.
- handle events related to browser extensions
-
-
-
- Represents a new V8 extension to be registered.
-
-
-
-
- Gets the name of the extension.
-
-
-
-
- Gets the javascript extension code
-
-
-
-
- Creates a new CwefExtension instance with a given name.
-
- Name of the CefExtension
- The javascript extension code.
-
-
-
- CefLibraryHandle is a SafeHandle that Loads libcef.dll and relesases it when disposed/finalized
- Calls LoadLibraryEx with LoadLibraryFlags.LOAD_WITH_ALTERED_SEARCH_PATH
- Make sure to set settings.BrowserSubprocessPath and settings.LocalesDirPath
-
- Adapted from http://www.pinvoke.net/default.aspx/kernel32.loadlibraryex
-
-
-
- In general not a fan of having inline classes/enums
- In this case it's not something that I'd like to see exposed
- as it's just a helper and outside the scope of the project
-
-
-
-
- Javascript exception
-
-
-
-
- Message
-
-
-
-
- Stack trace in javascript frames
-
-
-
-
- Javascript binding extension methods
-
-
-
-
- Make sure an object is bound in javascript. Executes against the main frame
-
- browser
- object names
- List of objects that were bound
-
-
-
- Represents an IME composition underline.
-
-
-
-
- Underline character range.
-
-
-
-
- Text color. 32-bit ARGB color value, not premultiplied. The color components are always
- in a known order. Equivalent to the SkColor type.
-
-
-
-
- Background color. 32-bit ARGB color value, not premultiplied. The color components are always
- in a known order. Equivalent to the SkColor type.
-
-
-
-
- true for thickunderline
-
-
-
-
- Struct representing cursor information.
-
-
-
-
- Cursor buffer
-
-
-
-
- Hotspot
-
-
-
-
- Image scale factor
-
-
-
-
- Size
-
-
-
-
- CursorInfo
-
- buffer
- hotspot
- image scale factor
- size
-
-
-
- Class representing a point.
-
-
-
-
- X coordinate
-
-
-
-
- Y coordinate
-
-
-
-
- Point
-
- x coordinate
- y coordinate
-
-
-
- Structure representing a size.
-
-
-
-
- Width
-
-
-
-
- Height
-
-
-
-
- Size
-
- width
- height
-
-
-
- Represents a range
-
-
-
-
- From
-
-
-
-
- To
-
-
-
-
- Range
-
- from
- to
-
-
-
- Represents a rectangle
-
-
-
-
- X coordinate
-
-
-
-
- Y coordinate
-
-
-
-
- Width
-
-
-
-
- Height
-
-
-
-
- Rect
-
- x coordinate
- y coordinate
- width
- height
-
-
-
- Class representing the virtual screen information for use when window
- rendering is disabled.
-
-
- See also Chrome Source
-
-
-
-
- Device scale factor. Specifies the ratio between physical and logical pixels.
-
-
-
-
- The screen depth in bits per pixel.
-
-
-
-
- The bits per color component. This assumes that the colors are balanced equally.
-
-
-
-
- This can be true for black and white printers.
-
-
-
-
- This is set from the rcMonitor member of MONITORINFOEX, to whit:
- "A RECT structure that specifies the display monitor rectangle,
- expressed in virtual-screen coordinates. Note that if the monitor
- is not the primary display monitor, some of the rectangle's
- coordinates may be negative values."
- The Rect and AvailableRect properties are used to determine the
- available surface for rendering popup views.
-
-
-
-
- This is set from the rcWork member of MONITORINFOEX, to whit:
- "A RECT structure that specifies the work area rectangle of the
- display monitor that can be used by applications, expressed in
- virtual-screen coordinates. Windows uses this rectangle to
- maximize an application on the monitor. The rest of the area in
- rcMonitor contains system windows such as the task bar and side
- bars. Note that if the monitor is not the primary display monitor,
- some of the rectangle's coordinates may be negative values".
-
- The Rect and AvailableRect properties are used to determine the
- available surface for rendering popup views.
-
-
-
-
- Represents a node in the browser's DOM.
-
-
-
-
- Representing a draggable region.
-
-
-
-
- Width
-
-
-
-
- Height
-
-
-
-
- X coordinate
-
-
-
-
- Y coordinate
-
-
-
-
- Is this region draggable
-
-
-
-
- Creates a new DraggableRegion
-
- width
- height
- x coordinate
- y coordinate
- is draggable?
-
-
-
- Lists the errors that can be reported during Widevine Content Decryption Module (CDM) registration.
-
-
-
-
- No error. Registration completed successfully.
-
-
-
-
- Required files or manifest contents are missing.
-
-
-
-
- The CDM is incompatible with the current Chromium version.
-
-
-
-
- CDM registration is not supported at this time.
-
-
-
-
- Lists some of the error codes that can be reported by CEF.
-
- For a complete up-to-date list, see the CEF source code
- (cef_errorcode_t in include/internal/cef_types.h)
- and the Chromium source code (net/base/net_error_list.h).
-
-
-
-
- No error occurred.
-
-
-
-
- An asynchronous IO operation is not yet complete. This usually does not
- indicate a fatal error. Typically this error will be generated as a
- notification to wait for some external notification that the IO operation
- finally completed.
-
-
-
-
- A generic failure occurred.
-
-
-
-
- A request was aborted, possibly by the user.
-
-
-
-
- An argument to the function is incorrect.
-
-
-
-
- The handle or file descriptor is invalid.
-
-
-
-
- The file or directory cannot be found.
-
-
-
-
- An operation timed out.
-
-
-
-
- The file is too large.
-
-
-
-
- An unexpected error. This may be caused by a programming mistake or an invalid assumption
-
-
-
-
- Permission to access a resource, other than the network, was denied.
-
-
-
-
- The operation failed because of unimplemented functionality.
-
-
-
-
- There were not enough resources to complete the operation.
-
-
-
-
- Memory allocation failed.
-
-
-
-
- The file upload failed because the file's modification time was different
- from the expectation.
-
-
-
-
- The socket is not connected.
-
-
-
-
- The file already exists.
-
-
-
-
- The path or file name is too long.
-
-
-
-
- Not enough room left on the disk.
-
-
-
-
- The file has a virus.
-
-
-
-
- The client chose to block the request.
-
-
-
-
- The network changed.
-
-
-
-
- The request was blocked by the URL blacklist configured by the domain
- administrator.
-
-
-
-
- The socket is already connected.
-
-
-
-
- The request was blocked because the forced reenrollment check is still
- pending. This error can only occur on ChromeOS.
- The error can be emitted by code in chrome/browser/policy/policy_helpers.cc.
-
-
-
-
- A connection was closed (corresponding to a TCP FIN).
-
-
-
-
- A connection was reset (corresponding to a TCP RST).
-
-
-
-
- A connection attempt was refused.
-
-
-
-
- A connection timed out as a result of not receiving an ACK for data sent.
- This can include a FIN packet that did not get ACK'd.
-
-
-
-
- A connection attempt failed.
-
-
-
-
- The host name could not be resolved.
-
-
-
-
- The Internet connection has been lost.
-
-
-
-
- An SSL protocol error occurred.
-
-
-
-
- The IP address or port number is invalid (e.g., cannot connect to the IP address 0 or the port 0).
-
-
-
-
- The IP address is unreachable. This usually means that there is no route to the specified host or network.
-
-
-
-
- The server requested a client certificate for SSL client authentication.
-
-
-
-
- A tunnel connection through the proxy could not be established.
-
-
-
-
- No SSL protocol versions are enabled.
-
-
-
-
- The client and server don't support a common SSL protocol version or cipher suite.
-
-
-
-
- The server requested a renegotiation (rehandshake).
-
-
-
-
- The proxy requested authentication (for tunnel establishment) with an
- unsupported method.
-
-
-
-
- During SSL renegotiation (rehandshake), the server sent a certificate with
- an error.
-
- Note: this error is not in the -2xx range so that it won't be handled as a
- certificate error.
-
-
-
-
- The SSL handshake failed because of a bad or missing client certificate.
-
-
-
-
- A connection attempt timed out.
-
-
-
-
- There are too many pending DNS resolves, so a request in the queue was
- aborted.
-
-
-
-
- Failed establishing a connection to the SOCKS proxy server for a target host.
-
-
-
-
- The SOCKS proxy server failed establishing connection to the target host
- because that host is unreachable.
-
-
-
-
- The request to negotiate an alternate protocol failed.
-
-
-
-
- The peer sent an SSL no_renegotiation alert message.
-
-
-
-
- Winsock sometimes reports more data written than passed. This is probably
- due to a broken LSP.
-
-
-
-
- An SSL peer sent us a fatal decompression_failure alert. This typically
- occurs when a peer selects DEFLATE compression in the mistaken belief that
- it supports it.
-
-
-
-
- An SSL peer sent us a fatal bad_record_mac alert. This has been observed
- from servers with buggy DEFLATE support.
-
-
-
-
- The proxy requested authentication (for tunnel establishment).
-
-
-
-
- A known TLS strict server didn't offer the renegotiation extension.
-
-
-
-
- The SSL server attempted to use a weak ephemeral Diffie-Hellman key.
-
-
-
-
- Could not create a connection to the proxy server. An error occurred
- either in resolving its name, or in connecting a socket to it.
- Note that this does NOT include failures during the actual "CONNECT" method
- of an HTTP proxy.
-
-
-
-
- A mandatory proxy configuration could not be used. Currently this means
- that a mandatory PAC script could not be fetched, parsed or executed.
-
-
-
-
- We've hit the max socket limit for the socket pool while preconnecting. We
- don't bother trying to preconnect more sockets.
-
-
-
-
- The permission to use the SSL client certificate's private key was denied.
-
-
-
-
- The SSL client certificate has no private key.
-
-
-
-
- The certificate presented by the HTTPS Proxy was invalid.
-
-
-
-
- An error occurred when trying to do a name resolution (DNS).
-
-
-
-
- Permission to access the network was denied. This is used to distinguish
- errors that were most likely caused by a firewall from other access denied
- errors. See also ERR_ACCESS_DENIED.
-
-
-
-
- The request throttler module cancelled this request to avoid DDOS.
-
-
-
-
- A request to create an SSL tunnel connection through the HTTPS proxy
- received a non-200 (OK) and non-407 (Proxy Auth) response. The response
- body might include a description of why the request failed.
-
-
-
-
- We were unable to sign the CertificateVerify data of an SSL client auth
- handshake with the client certificate's private key.
-
- Possible causes for this include the user implicitly or explicitly
- denying access to the private key, the private key may not be valid for
- signing, the key may be relying on a cached handle which is no longer
- valid, or the CSP won't allow arbitrary data to be signed.
-
-
-
-
- The message was too large for the transport. (for example a UDP message
- which exceeds size threshold).
-
-
-
-
- A SPDY session already exists, and should be used instead of this connection.
-
-
-
-
- Websocket protocol error. Indicates that we are terminating the connection
- due to a malformed frame or other protocol violation.
-
-
-
-
- Connection was aborted for switching to another ptotocol.
- WebSocket abort SocketStream connection when alternate protocol is found.
-
-
-
-
- Returned when attempting to bind an address that is already in use.
-
-
-
-
- An operation failed because the SSL handshake has not completed.
-
-
-
-
- SSL peer's public key is invalid.
-
-
-
-
- The certificate didn't match the built-in public key pins for the host name.
- The pins are set in net/http/transport_security_state.cc and require that
- one of a set of public keys exist on the path from the leaf to the root.
-
-
-
-
- Server request for client certificate did not contain any types we support.
-
-
-
-
- Server requested one type of cert, then requested a different type while the
- first was still being generated.
-
-
-
-
- An SSL peer sent us a fatal decrypt_error alert. This typically occurs when
- a peer could not correctly verify a signature (in CertificateVerify or
- ServerKeyExchange) or validate a Finished message.
-
-
-
-
- There are too many pending WebSocketJob instances, so the new job was not
- pushed to the queue.
-
-
-
-
- There are too many active SocketStream instances, so the new connect request
- was rejected.
-
-
-
-
- The SSL server certificate changed in a renegotiation.
-
-
-
-
- The SSL server indicated that an unnecessary TLS version fallback was
- performed.
-
-
-
-
- Certificate Transparency: All Signed Certificate Timestamps failed to verify.
-
-
-
-
- The SSL server sent us a fatal unrecognized_name alert.
-
-
-
-
- Failed to set the socket's receive buffer size as requested.
-
-
-
-
- Failed to set the socket's send buffer size as requested.
-
-
-
-
- Failed to set the socket's receive buffer size as requested, despite success
- return code from setsockopt.
-
-
-
-
- Failed to set the socket's send buffer size as requested, despite success
- return code from setsockopt.
-
-
-
-
- Failed to import a client certificate from the platform store into the SSL
- library.
-
-
-
-
- The server responded with a certificate whose common name did not match the host name.
- This could mean:
- 1. An attacker has redirected our traffic to his server and is presenting a certificate
- for which he knows the private key.
- 2. The server is misconfigured and responding with the wrong cert.
- 3. The user is on a wireless network and is being redirected to the network's login page.
- 4. The OS has used a DNS search suffix and the server doesn't have a certificate for the
- abbreviated name in the address bar.
-
-
-
-
- The server responded with a certificate that, by our clock, appears to either not yet be valid or to have expired.
- This could mean:
- 1. An attacker is presenting an old certificate for which he has managed to obtain the private key
- 2. The server is misconfigured and is not presenting a valid cert.
- 3. Our clock is wrong.
-
-
-
-
- The server responded with a certificate that is signed by an authority we don't trust.
- The could mean:
- 1. An attacker has substituted the real certificate for a cert that
- contains his public key and is signed by his cousin.
- 2. The server operator has a legitimate certificate from a CA we don't know about, but should trust.
- 3. The server is presenting a self-signed certificate, providing no defense against active attackers (but foiling passive attackers).
-
-
-
-
- The server responded with a certificate that contains errors. This error is not recoverable.
- MSDN describes this error as follows:
- "The SSL certificate contains errors."
- NOTE: It's unclear how this differs from ERR_CERT_INVALID. For consistency,
- use that code instead of this one from now on.
-
-
-
-
- The certificate has no mechanism for determining if it is revoked. In effect, this certificate cannot be revoked.
-
-
-
-
- Revocation information for the security certificate for this site is not available.
- This could mean:
- 1. An attacker has compromised the private key in the certificate and is blocking our attempt to
- find out that the cert was revoked.
- 2. The certificate is unrevoked, but the revocation server is busy or unavailable.
-
-
-
-
- The server responded with a certificate has been revoked.
- We have the capability to ignore this error, but it is probably not the thing to do.
-
-
-
-
- The server responded with a certificate that is invalid. This error is not recoverable.
-
-
-
-
- The server responded with a certificate that is signed using a weak
- signature algorithm.
-
-
-
-
- The host name specified in the certificate is not unique.
-
-
-
-
- The server responded with a certificate that contains a weak key (e.g.
- a too-small RSA key).
-
-
-
-
- The certificate claimed DNS names that are in violation of name constraints.
-
-
-
-
- Add new certificate error codes here.
-
- Update the value of CERT_END whenever you add a new certificate error
- code.
-
- The value immediately past the last certificate error code.
-
-
-
-
- The URL is invalid.
-
-
-
-
- The scheme of the URL is disallowed.
-
-
-
-
- The scheme of the URL is unknown.
-
-
-
-
- Attempting to load an URL resulted in too many redirects.
-
-
-
-
- Attempting to load an URL resulted in an unsafe redirect (e.g., a redirect to file:// is considered unsafe).
-
-
-
-
- Attempting to load an URL with an unsafe port number. These are port
- numbers that correspond to services, which are not robust to spurious input
- that may be constructed as a result of an allowed web construct (e.g., HTTP
- looks a lot like SMTP, so form submission to port 25 is denied).
-
-
-
-
- The server's response was invalid.
-
-
-
-
- Error in chunked transfer encoding.
-
-
-
-
- The server did not support the request method.
-
-
-
-
- The response was 407 (Proxy Authentication Required), yet we did not send the request to a proxy.
-
-
-
-
- The server closed the connection without sending any data.
-
-
-
-
- The headers section of the response is too large.
-
-
-
-
- The PAC requested by HTTP did not have a valid status code (non-200).
-
-
-
-
- The evaluation of the PAC script failed.
-
-
-
-
- The response was 416 (Requested range not satisfiable) and the server cannot
- satisfy the range requested.
-
-
-
-
- The identity used for authentication is invalid.
-
-
-
-
- Content decoding of the response body failed.
-
-
-
-
- An operation could not be completed because all network IO
- is suspended.
-
-
-
-
- FLIP data received without receiving a SYN_REPLY on the stream.
-
-
-
-
- Converting the response to target encoding failed.
-
-
-
-
- The server sent an FTP directory listing in a format we do not understand.
-
-
-
-
- Attempted use of an unknown SPDY stream id.
-
-
-
-
- There are no supported proxies in the provided list.
-
-
-
-
- There is a SPDY protocol error.
-
-
-
-
- Credentials could not be established during HTTP Authentication.
-
-
-
-
- An HTTP Authentication scheme was tried which is not supported on this
- machine.
-
-
-
-
- Detecting the encoding of the response failed.
-
-
-
-
- (GSSAPI) No Kerberos credentials were available during HTTP Authentication.
-
-
-
-
- An unexpected, but documented, SSPI or GSSAPI status code was returned.
-
-
-
-
- The environment was not set up correctly for authentication (for
- example, no KDC could be found or the principal is unknown.
-
-
-
-
- An undocumented SSPI or GSSAPI status code was returned.
-
-
-
-
- The HTTP response was too big to drain.
-
-
-
-
- The HTTP response contained multiple distinct Content-Length headers.
-
-
-
-
- SPDY Headers have been received, but not all of them - status or version
- headers are missing, so we're expecting additional frames to complete them.
-
-
-
-
- No PAC URL configuration could be retrieved from DHCP. This can indicate
- either a failure to retrieve the DHCP configuration, or that there was no
- PAC URL configured in DHCP.
-
-
-
-
- The HTTP response contained multiple Content-Disposition headers.
-
-
-
-
- The HTTP response contained multiple Location headers.
-
-
-
-
- SPDY server refused the stream. Client should retry. This should never be a
- user-visible error.
-
-
-
-
- SPDY server didn't respond to the PING message.
-
-
-
-
- The HTTP response body transferred fewer bytes than were advertised by the
- Content-Length header when the connection is closed.
-
-
-
-
- The HTTP response body is transferred with Chunked-Encoding, but the
- terminating zero-length chunk was never sent when the connection is closed.
-
-
-
-
- There is a QUIC protocol error.
-
-
-
-
- The HTTP headers were truncated by an EOF.
-
-
-
-
- The QUIC crytpo handshake failed. This means that the server was unable
- to read any requests sent, so they may be resent.
-
-
-
-
- An https resource was requested over an insecure QUIC connection.
-
-
-
-
- Transport security is inadequate for the SPDY version.
-
-
-
-
- The peer violated SPDY flow control.
-
-
-
-
- The peer sent an improperly sized SPDY frame.
-
-
-
-
- Decoding or encoding of compressed SPDY headers failed.
-
-
-
-
- Proxy Auth Requested without a valid Client Socket Handle.
-
-
-
-
- The cache does not have the requested entry.
-
-
-
-
- Unable to read from the disk cache.
-
-
-
-
- Unable to write to the disk cache.
-
-
-
-
- The operation is not supported for this entry.
-
-
-
-
- The disk cache is unable to open this entry.
-
-
-
-
- The disk cache is unable to create this entry.
-
-
-
-
- Multiple transactions are racing to create disk cache entries. This is an
- internal error returned from the HttpCache to the HttpCacheTransaction that
- tells the transaction to restart the entry-creation logic because the state
- of the cache has changed.
-
-
-
-
- The cache was unable to read a checksum record on an entry. This can be
- returned from attempts to read from the cache. It is an internal error,
- returned by the SimpleCache backend, but not by any URLRequest methods
- or members.
-
-
-
-
- The cache found an entry with an invalid checksum. This can be returned from
- attempts to read from the cache. It is an internal error, returned by the
- SimpleCache backend, but not by any URLRequest methods or members.
-
-
-
-
- Internal error code for the HTTP cache. The cache lock timeout has fired.
-
-
-
-
- The server's response was insecure (e.g. there was a cert error).
-
-
-
-
- The server responded to a <keygen> with a generated client cert that we
- don't have the matching private key for.
-
-
-
-
- An error adding to the OS certificate database (e.g. OS X Keychain).
-
-
-
-
- A generic error for failed FTP control connection command.
- If possible, please use or add a more specific error code.
-
-
-
-
- The server cannot fulfill the request at this point. This is a temporary
- error.
- FTP response code 421.
-
-
-
-
- The server has aborted the transfer.
- FTP response code 426.
-
-
-
-
- The file is busy, or some other temporary error condition on opening
- the file.
- FTP response code 450.
-
-
-
-
- Server rejected our command because of syntax errors.
- FTP response codes 500, 501.
-
-
-
-
- Server does not support the command we issued.
- FTP response codes 502, 504.
-
-
-
-
- Server rejected our command because we didn't issue the commands in right
- order.
- FTP response code 503.
-
-
-
-
- PKCS #12 import failed due to incorrect password.
-
-
-
-
- PKCS #12 import failed due to other error.
-
-
-
-
- CA import failed - not a CA cert.
-
-
-
-
- Import failed - certificate already exists in database.
- Note it's a little weird this is an error but reimporting a PKCS12 is ok
- (no-op). That's how Mozilla does it, though.
-
-
-
-
- CA import failed due to some other error.
-
-
-
-
- Server certificate import failed due to some internal error.
-
-
-
-
- PKCS #12 import failed due to invalid MAC.
-
-
-
-
- PKCS #12 import failed due to invalid/corrupt file.
-
-
-
-
- PKCS #12 import failed due to unsupported features.
-
-
-
-
- Key generation failed.
-
-
-
-
- Server-bound certificate generation failed.
-
-
-
-
- Failure to export private key.
-
-
-
-
- Self-signed certificate generation failed.
-
-
-
-
- The certificate database changed in some way.
-
-
-
-
- Failure to import Channel ID.
-
-
-
-
- DNS resolver received a malformed response.
-
-
-
-
- DNS server requires TCP
-
-
-
-
- DNS server failed. This error is returned for all of the following
- error conditions:
- 1 - Format error - The name server was unable to interpret the query.
- 2 - Server failure - The name server was unable to process this query
- due to a problem with the name server.
- 4 - Not Implemented - The name server does not support the requested
- kind of query.
- 5 - Refused - The name server refuses to perform the specified
- operation for policy reasons.
-
-
-
-
- DNS transaction timed out.
-
-
-
-
- The entry was not found in cache, for cache-only lookups.
-
-
-
-
- Suffix search list rules prevent resolution of the given host name.
-
-
-
-
- Failed to sort addresses according to RFC3484.
-
-
-
-
- Supported event bit flags.
-
-
-
-
- Mac OS-X command key.
-
-
-
-
- CefFileDialogMode (Based on cef_file_dialog_mode_t)
-
-
-
-
- Requires that the file exists before allowing the user to pick it.
-
-
-
-
- Like Open, but allows picking multiple files to open.
-
-
-
-
- Like Open, but selects a folder to open.
-
-
-
-
- Allows picking a nonexistent file, and prompts to overwrite if the file already exists.
-
-
-
-
- Focus Source
-
-
-
-
- The source is explicit navigation via the API (LoadURL(), etc).
-
-
-
-
- The source is a system-generated focus event.
-
-
-
-
- Supported JavaScript dialog types.
-
-
-
-
- Custom menu items originating from the renderer process. For example, plugin placeholder menu items or Flash menu items.
- This is the first entry
-
-
-
-
- Custom menu items originating from the renderer process. For example, plugin placeholder menu items or Flash menu items.
- This is the last entry
-
-
-
-
- Margin type for PDF printing.
-
-
-
-
- Default margins.
-
-
-
-
- No margins.
-
-
-
-
- Minimum margins
-
-
-
-
- Custom margins.
-
-
-
-
- Return value types.
-
-
-
-
- Cancel immediately.
-
-
-
-
- Continue immediately.
-
-
-
-
- Continue asynchronously (usually via a callback).
-
-
-
-
- Represents the state of a setting.
-
-
-
-
- Use the default state for the setting.
-
-
-
-
- Enable or allow the setting.
-
-
-
-
- Disable or disallow the setting.
-
-
-
-
- Process termination status values.
-
-
-
-
- Non-zero exit status.
-
-
-
-
- SIGKILL or task manager kill.
-
-
-
-
- Segmentation fault.
-
-
-
-
- Out of memory. Some platforms may use ProcessCrashed instead.
-
-
-
-
- Managed enum for cef_thread_id_t/CefThreadId
-
-
-
-
- The CEF UI thread in the browser. In CefSharp this is ALWAYS
- separate from the application's main thread (and thus the main
- WinForm UI thread).
-
-
-
-
- Used to interact with the database.
-
-
-
-
- Used to interact with the file system.
-
-
-
-
- Used for file system operations that block user interactions.
- Responsiveness of this thread affects users.
-
-
-
-
- Used to launch and terminate browser processes.
-
-
-
-
- Used to handle slow HTTP cache operations.
-
-
-
-
- Used to process IPC and network messages.
-
-
-
-
- The main thread in the renderer. Used for all WebKit and V8 interaction.
-
-
-
-
-
- Supported certificate status code values. See net\cert\cert_status_flags.h
- for more information. CERT_STATUS_NONE is new in CEF because we use an
- enum while cert_status_flags.h uses a typedef and static const variables.
-
-
-
-
- Supported context menu edit state bit flags.
-
-
-
-
- Supported context menu media state bit flags.
-
-
-
-
- Supported context menu media types.
-
-
-
-
- No special node is in context.
-
-
-
-
- An image node is selected.
-
-
-
-
- A video node is selected.
-
-
-
-
- An audio node is selected.
-
-
-
-
- A file node is selected.
-
-
-
-
- A plugin node is selected.
-
-
-
-
- ContextMenuType
-
-
-
-
- No node is selected.
-
-
-
-
- The top page is selected.
-
-
-
-
- A subframe page is selected.
-
-
-
-
- A link is selected.
-
-
-
-
- A media node is selected.
-
-
-
-
- There is a textual or mixed selection that is selected.
-
-
-
-
- An editable element is selected.
-
-
-
-
- Return values for IResponseFilter
-
-
-
-
- Some or all of the pre-filter data was read successfully but more data is
- needed in order to continue filtering (filtered output is pending).
-
-
-
-
- Some or all of the pre-filter data was read successfully and all available filtered output has been written.
-
-
-
-
- An error occurred during filtering.
-
-
-
-
- Notification that a key transitioned from "up" to "down".
-
-
-
-
- Notification that a key was pressed. This does not necessarily correspond
- to a character depending on the key and language. Use KEYEVENT_CHAR for
- character input.
-
-
-
-
- Notification that a key was released.
-
-
-
-
- Notification that a character was typed. Use this for text input. Key
- down events may generate 0, 1, or more than one character event depending
- on the key, locale, and operating system.
-
-
-
-
- Default logging (currently Info logging)
-
-
-
-
- Verbose logging.
-
-
-
-
- Info logging
-
-
-
-
- Warning logging
-
-
-
-
- Error logging
-
-
-
-
- Completely disable logging
-
-
-
-
- Paint element types.
-
-
-
-
- Plugin policies supported by IPluginHandler.OnBeforePluginLoad.
-
-
-
-
- Allow the content
-
-
-
-
- Allow important content and block unimportant content based on heuristics. The user can manually load blocked content.
-
-
-
-
- Block the content. The user can manually load blocked content.
-
-
-
-
- Disable the content. The user cannot load disabled content.
-
-
-
-
- Post data elements may represent either bytes or files.
-
-
-
-
- Always send the complete Referrer value.
-
-
-
-
- Use the default policy. This is OriginWhenCrossOrigin
- when the `--reduced-referrer-granularity` command-line flag is specified
- and NoReferrerWhenDowngrade otherwise.
-
-
-
-
- When navigating from HTTPS to HTTP do not send the Referrer value.
- Otherwise, send the complete Referrer value.
-
-
-
-
- Never send the Referrer value.
-
-
-
-
- Only send the origin component of the Referrer value.
-
-
-
-
- When navigating cross-origin only send the origin component of the Referrer value. Otherwise, send the complete Referrer value.
-
-
-
-
- Resource type for a request.
-
-
-
-
- Top level page.
-
-
-
-
- Frame or iframe.
-
-
-
-
- CSS stylesheet.
-
-
-
-
- External script.
-
-
-
-
- Image (jpg/gif/png/etc).
-
-
-
-
- Font.
-
-
-
-
- Some other subresource. This is the default type if the actual type is unknown.
-
-
-
-
- Object (or embed) tag for a plugin, or a resource that a plugin requested.
-
-
-
-
- Media resource.
-
-
-
-
- Main resource of a dedicated worker.
-
-
-
-
- Main resource of a shared worker.
-
-
-
-
- Explicitly requested prefetch.
-
-
-
-
- Favicon.
-
-
-
-
- XMLHttpRequest.
-
-
-
-
- A request for a ping
-
-
-
-
- Main resource of a service worker.
-
-
-
-
- A report of Content Security Policy violations.
-
-
-
-
- A resource that a plugin requested.
-
-
-
-
- Supported SSL content status flags. See content/public/common/ssl_status.h
- for more information.
-
-
-
-
- Supported SSL version values. See net/ssl/ssl_connection_status_flags.h
- for more information.
-
-
-
-
- Transition type for a request. Made up of one source value and 0 or more qualifiers.
-
-
-
-
- Source is a link click or the JavaScript window.open function. This is
- also the default value for requests like sub-resource loads that are not navigations.
-
-
-
-
- Source is some other "explicit" navigation action such as creating a new
- browser or using the LoadURL function. This is also the default value
- for navigations where the actual type is unknown.
-
-
-
-
- Source is a subframe navigation. This is any content that is automatically
- loaded in a non-toplevel frame. For example, if a page consists of several
- frames containing ads, those ad URLs will have this transition type.
- The user may not even realize the content in these pages is a separate
- frame, so may not care about the URL.
-
-
-
-
- Source is a subframe navigation explicitly requested by the user that will
- generate new navigation entries in the back/forward list. These are
- probably more important than frames that were automatically loaded in
- the background because the user probably cares about the fact that this
- link was loaded.
-
-
-
-
- Source is a form submission by the user. NOTE: In some situations
- submitting a form does not result in this transition type. This can happen
- if the form uses a script to submit the contents.
-
-
-
-
- Source is a "reload" of the page via the Reload function or by re-visiting
- the same URL. NOTE: This is distinct from the concept of whether a
- particular load uses "reload semantics" (i.e. bypasses cached data).
-
-
-
-
- General mask defining the bits used for the source values.
-
-
-
-
- Attempted to visit a URL but was blocked.
-
-
-
-
- Used the Forward or Back function to navigate among browsing history.
-
-
-
-
- The beginning of a navigation chain.
-
-
-
-
- The last transition in a redirect chain.
-
-
-
-
- Redirects caused by JavaScript or a meta refresh tag on the page.
-
-
-
-
- Redirects sent from the server by HTTP headers.
-
-
-
-
- Used to test whether a transition involves a redirect.
-
-
-
-
- General mask defining the bits used for the qualifiers.
-
-
-
-
- Flags that represent CefURLRequest status.
-
-
-
-
- Unknown status.
-
-
-
-
- Request succeeded.
-
-
-
-
- An IO request is pending, and the caller will be informed when it is completed.
-
-
-
-
- Request was canceled programatically.
-
-
-
-
- Request failed for some reason.
-
-
-
-
- The manner in which a link click should be opened.
-
-
-
-
- Event arguments for the AddressChanged event handler.
-
-
-
-
- Access to the underlying object
-
-
-
-
- The new address
-
-
-
-
- Creates a new AddressChangedEventArgs event argument.
-
- the browser object
- the address
-
-
-
- Event arguments for the ConsoleMessage event handler set up in IWebBrowser.
-
-
-
-
- Creates a new ConsoleMessageEventArgs event argument.
-
- level
- message
- source
- line number
-
-
-
- Log level
-
-
-
-
- The message text of the console message.
-
-
-
-
- The source of the console message.
-
-
-
-
- The line number that generated the console message.
-
-
-
-
- Event arguments to the FrameLoadEnd event handler set up in IWebBrowser.
-
-
-
-
- Creates a new FrameLoadEnd event args
-
- browser
- frame
- http statusCode
-
-
-
- The browser that contains the frame that finished loading.
-
-
-
-
- The frame that finished loading.
-
-
-
-
- The URL that was loaded.
-
-
-
-
- Http Status Code
-
-
-
-
- Event arguments to the FrameLoadStart event handler set up in IWebBrowser.
-
-
-
-
- Creates a new FrameLoadStart event args
-
- browser
- frame
- provides information about the source of the navigation and an accurate value is only
- available in the browser process
-
-
-
- The browser object
-
-
-
-
- The frame that just started loading.
-
-
-
-
- The URL that was loaded.
-
-
-
-
- TransitionType provides information about the source of the navigation.
-
-
-
-
- Event arguments for the IsBrowserInitializedChanged event handler.
- TODO: Remove this event args, we don't actually use it (event is only fired once)
-
-
-
-
- Is browser initialized
-
-
-
-
- Default constructor
-
- bool
-
-
-
- Event arguments to the LoadError event handler set up in IWebBrowser.
-
-
-
-
- LoadErrorEventArgs
-
- browser
- frame
- error code
- error text
- failed url
-
-
-
- The browser object
-
-
-
-
- The frame that failed to load.
-
-
-
-
- The URL that failed to load.
-
-
-
-
- The error code.
-
-
-
-
- The error text.
-
-
-
-
- Event arguments to the LoadingStateChanged event handler set up in IWebBrowser.
-
-
-
-
- Returns true if the browser can navigate forwards.
-
-
-
-
- Returns true if the browser can navigate backwards.
-
-
-
-
- Returns true if the browser can reload.
-
-
-
-
- Returns true if the browser is loading.
-
-
-
-
- Access to the underlying object
-
-
-
-
- LoadingStateChangedEventArgs
-
- browser
- can go back
- can go forward
- is loading
-
-
-
- Event arguments to the StatusMessage event handler set up in IWebBrowser.
-
-
-
-
- StatusMessageEventArgs
-
- browser
- status message value
-
-
-
- The browser object
-
-
-
-
- The value of the status message.
-
-
-
-
- Event arguments to the TitleChanged event handler.
-
-
-
-
- The new title
-
-
-
-
- Creates a new TitleChanged event arg
-
- the new title
-
-
-
- Implement this interface to handle events related to browser process callbacks.
- The methods of this class will be called on the CEF UI thread unless otherwise indicated. .
-
-
-
-
- Called on the CEF UI thread immediately after the CEF context has been initialized.
- You can now access the Global RequestContext through Cef.GetGlobalRequestContext() - this is the
- first place you can set Preferences (e.g. proxy settings, spell check dictionaries).
-
-
-
-
- Called from any thread when work has been scheduled for the browser process
- main (UI) thread. This callback is used in combination with CefSettings.
- ExternalMessagePump and Cef.DoMessageLoopWork() in cases where the CEF
- message loop must be integrated into an existing application message loop
- (see additional comments and warnings on Cef.DoMessageLoopWork). This
- callback should schedule a Cef.DoMessageLoopWork() call to happen on the
- main (UI) thread.
-
- is the requested delay in milliseconds. If
- delay is less than or equal to 0 then the call should happen reasonably soon. If
- delay is greater than 0 then the call should be scheduled to happen after the
- specified delay and any currently pending scheduled call should be
- cancelled.
-
-
-
- Implement this interface to handle context menu events.
-
-
-
-
- Called before a context menu is displayed. The model can be cleared to show no context menu or
- modified to show a custom menu.
-
- the ChromiumWebBrowser control
- the browser object
- The frame the request is coming from
- provides information about the context menu state
- initially contains the default context menu
-
-
-
- Called to execute a command selected from the context menu. See
- cef_menu_id_t for the command ids that have default implementations. All
- user-defined command ids should be between MENU_ID_USER_FIRST and
- MENU_ID_USER_LAST.
-
- the ChromiumWebBrowser control
- the browser object
- The frame the request is coming from
- will have the same values as what was passed to
- menu command id
- event flags
- Return true if the command was handled or false for the default implementation.
-
-
-
- Called when the context menu is dismissed irregardless of whether the menu
- was empty or a command was selected.
-
- the ChromiumWebBrowser control
- the browser object
- The frame the request is coming from
-
-
-
- Called to allow custom display of the context menu.
- For custom display return true and execute callback either synchronously or asynchronously with the selected command Id.
- For default display return false. Do not keep references to parameters or model outside of this callback.
-
- the ChromiumWebBrowser control
- the browser object
- The frame the request is coming from
- provides information about the context menu state
- contains the context menu model resulting from OnBeforeContextMenu
- the callback to execute for custom display
- For custom display return true and execute callback either synchronously or asynchronously with the selected command ID.
-
-
-
- Implement this interface to handle dialog events. The methods of this class will be called on the CEF UI thread.
-
-
-
-
- Runs a file chooser dialog.
-
-
- To test assign something like TempFileDialogHandler (from CefSharp.Example) to DialogHandler e.g.
-
- browser.DialogHandler = new TempFileDialogHandler();
-
- Example URL to use for file browsing http://www.cs.tut.fi/~jkorpela/forms/file.html#example
- Simply click browse, the space next to the browse button should be populated with a randomly generated filename.
-
- the ChromiumWebBrowser control
- the browser object
- represents the type of dialog to display
- further specifies behavior dialog should exhibit
- the title to be used for the dialog. It may be empty to show the default title ("Open" or "Save"
- depending on the mode).
- is the path with optional directory and/or file name component that
- should be initially selected in the dialog.
- are used to restrict the selectable file types and may any combination of
- (a) valid lower-cased MIME types (e.g. "text/*" or "image/*"),
- (b) individual file extensions (e.g. ".txt" or ".png"),
- (c) combined description and file extension delimited using "|" and ";" (e.g. "Image Types|.png;.gif;.jpg").
- is the 0-based index of the filter that should be selected by default.
- Callback interface for asynchronous continuation of file dialog requests.
- To display a custom dialog return true. To display the default dialog return false.
-
-
-
- Handle events related to browser display state.
-
-
-
-
- Called when a frame's address has changed.
-
- the ChromiumWebBrowser control
- args
-
-
-
- Called when auto-resize is enabled via IBrowserHost.SetAutoResizeEnabled and the contents have auto-resized.
-
- the ChromiumWebBrowser control
- the browser object
- will be the desired size in view coordinates
- Return true if the resize was handled or false for default handling.
-
-
-
- Called when the page title changes.
-
- the ChromiumWebBrowser control
- args
-
-
-
- Called when the page icon changes.
-
- the ChromiumWebBrowser control
- the browser object
- list of urls where the favicons can be downloaded
-
-
-
- Called when web content in the page has toggled fullscreen mode. The client is
- responsible for resizing the browser if desired.
-
- The ChromiumWebBrowser control
- the browser object
- If true the content will automatically be sized to fill the browser content area.
- If false the content will automatically return to its original size and position.
-
-
-
- Called when the browser is about to display a tooltip. text contains the
- text that will be displayed in the tooltip. You can optionally modify text
- and then return false to allow the browser to display the tooltip.
- When window rendering is disabled the application is responsible for
- drawing tooltips and the return value is ignored.
-
- The ChromiumWebBrowser control
- the text that will be displayed in the tooltip
- To handle the display of the tooltip yourself return true otherwise return false
- to allow the browser to display the tooltip.
- Only called when using Off-screen rendering (WPF and OffScreen)
-
-
-
- Called when the browser receives a status message.
-
- The control this popup is related to.
- args
-
-
-
- Called to display a console message.
-
- The ChromiumWebBrowser control
- args
- Return true to stop the message from being output to the console.
-
-
-
- Class used to handle file downloads.
- The methods of this class will called on the CEF UI thread.
-
-
-
-
- Called before a download begins.
-
- the ChromiumWebBrowser control
- The browser instance
- Represents the file being downloaded.
- Callback interface used to asynchronously continue a download.
-
-
-
- Called when a download's status or progress information has been updated. This may be called multiple times before and after .
-
- the ChromiumWebBrowser control
- The browser instance
- Represents the file being downloaded.
- The callback used to Cancel/Pause/Resume the process
-
-
-
- Implement this interface to handle events related to dragging.
- The methods of this class will be called on the UI thread.
-
-
-
-
- Called when an external drag event enters the browser window.
-
- the ChromiumWebBrowser control
- the browser object
- contains the drag event data
- represents the type of drag operation
- Return false for default drag handling behavior or true to cancel the drag event.
-
-
-
- Called whenever draggable regions for the browser window change.
- These can be specified using the '-webkit-app-region: drag/no-drag' CSS-property.
- If draggable regions are never defined in a document this method will also never be called.
- If the last draggable region is removed from a document this method will be called with an empty IList.
-
- the ChromiumWebBrowser control
- the browser object
- List of objects or null if last region was removed.
-
-
-
- Implement this interface to handle events related to find results.
- The methods of this class will be called on the CEF UI thread.
-
-
-
-
- Called to report find results returned by
-
- the ChromiumWebBrowser control
- the browser object
- is the identifier passed to Find()
- is the number of matches currently identified
- is the location of where the match was found (in window coordinates)
- is the current position in the search results
- is true if this is the last find notification.
-
-
-
- Implement this interface to handle events related to focus.
- The methods of this class will be called on the CEF UI thread.
-
-
-
-
- Called when the browser component has received focus.
-
- the ChromiumWebBrowser control
- the browser object
-
-
-
- Called when the browser component is requesting focus.
-
- the ChromiumWebBrowser control
- the browser object, do not keep a reference to this object outside of this method
- Indicates where the focus request is originating from.
- Return false to allow the focus to be set or true to cancel setting the focus.
-
-
-
- Called when the browser component is about to lose focus.
- For instance, if focus was on the last HTML element and the user pressed the TAB key.
-
- the ChromiumWebBrowser control
- the browser object
- Will be true if the browser is giving focus to the next component
- and false if the browser is giving focus to the previous component.
-
-
-
- Implement this interface to handle events related to JavaScript dialogs.
- The methods of this class will be called on the CEF UI thread.
-
-
-
-
- Called to run a JavaScript dialog.
-
- the ChromiumWebBrowser control
- the browser object
- originating url
- Dialog Type
- Message Text
- value will be specified for prompt dialogs only
- Callback can be executed inline or in an async fashion
- Set suppressMessage to true and return false to suppress the message (suppressing messages is preferable to immediately executing the callback as this is used to detect presumably malicious behavior like spamming alert messages in onbeforeunload). Set suppressMessage to false and return false to use the default implementation (the default implementation will show one modal dialog at a time and suppress any additional dialog requests until the displayed dialog is dismissed).
- Return true if the application will use a custom dialog or if the callback has been executed immediately. Custom dialogs may be either modal or modeless. If a custom dialog is used the application must execute |callback| once the custom dialog is dismissed.
-
-
-
- Called to run a dialog asking the user if they want to leave a page. Return false to use the default dialog implementation.
- Return true if the application will use a custom dialog or if the callback has been executed immediately.
- Custom dialogs may be either modal or modeless. If a custom dialog is used the application must execute
- once the custom dialog is dismissed.
-
- the ChromiumWebBrowser control
- the browser object
- message text (optional)
- indicates a page reload
- Callback can be executed inline or in an async fashion
- Return false to use the default dialog implementation otherwise return true to handle with your own custom implementation.
-
-
-
- Called to cancel any pending dialogs and reset any saved dialog state. Will
- be called due to events like page navigation irregardless of whether any
- dialogs are currently pending.
-
- the ChromiumWebBrowser control
- the browser object
-
-
-
- Called when the default implementation dialog is closed.
-
- the ChromiumWebBrowser control
- the browser object
-
-
-
- Implement this interface to handle events related to keyboard input.
-
-
-
-
- Called before a keyboard event is sent to the renderer.
- Return true if the event was handled or false
- otherwise. If the event will be handled in as a keyboard
- shortcut set isKeyboardShortcut to true and return false.
-
- the ChromiumWebBrowser control
- The browser instance.
- Whether this was a key up/down/raw/etc...
-
- The Windows key code for the key event. This value is used by the DOM
- specification. Sometimes it comes directly from the event (i.e. on
- Windows) and sometimes it's determined using a mapping function. See
- WebCore/platform/chromium/KeyboardCodes.h for the list of values.
-
- The native key code. On Windows this appears to be in the format of WM_KEYDOWN/WM_KEYUP/etc... lParam data.
- What other modifier keys are currently down: Shift/Control/Alt/OS X Command/etc...
-
- Indicates whether the event is considered a "system key" event (see
- http://msdn.microsoft.com/en-us/library/ms646286(VS.85).aspx for details).
-
- See the summary for an explanation of when to set this to true.
- Returns true if the event was handled or false otherwise.
-
-
-
- Called after the renderer and JavaScript in the page has had a chance to
- handle the event. Return true if the keyboard event was handled or false otherwise.
-
- the ChromiumWebBrowser control
- The browser instance.
- Whether this was a key up/down/raw/etc...
-
- The Windows key code for the key event. This value is used by the DOM
- specification. Sometimes it comes directly from the event (i.e. on
- Windows) and sometimes it's determined using a mapping function. See
- WebCore/platform/chromium/KeyboardCodes.h for the list of values.
-
- The native key code. On Windows this appears to be in the format of WM_KEYDOWN/WM_KEYUP/etc... lParam data.
- What other modifier keys are currently down: Shift/Control/Alt/OS X Command/etc...
-
- Indicates whether the event is considered a "system key" event (see
- http://msdn.microsoft.com/en-us/library/ms646286(VS.85).aspx for details).
-
- Return true if the keyboard event was handled or false otherwise.
-
-
-
- Implement this interface to handle events related to browser life span.
- The methods of this class will be called on the CEF UI thread unless otherwise indicated.
-
-
-
-
- Called before a popup window is created.
-
- the ChromiumWebBrowser control
- The browser instance that launched this popup.
- The HTML frame that launched this popup.
- The URL of the popup content. (This may be empty/null)
- The name of the popup. (This may be empty/null)
- The value indicates where the user intended to
- open the popup (e.g. current tab, new tab, etc)
- The value will be true if the popup was opened via explicit user gesture
- (e.g. clicking a link) or false if the popup opened automatically (e.g. via the DomContentLoaded event).
- structure contains additional information about the requested popup window
- window information
- browser settings, defaults to source browsers
- value indicates whether the new browser window should be scriptable
- and in the same process as the source browser.
- EXPERIMENTAL - A newly created browser that will host the popup. Set to null
- for default behaviour.
- To cancel creation of the popup window return true otherwise return false.
-
- CEF documentation:
-
- Called on the IO thread before a new popup window is created. The |browser|
- and |frame| parameters represent the source of the popup request. The
- |target_url| and |target_frame_name| values may be empty if none were
- specified with the request. The |popupFeatures| structure contains
- information about the requested popup window. To allow creation of the
- popup window optionally modify |windowInfo|, |client|, |settings| and
- |no_javascript_access| and return false. To cancel creation of the popup
- window return true. The |client| and |settings| values will default to the
- source browser's values. The |no_javascript_access| value indicates whether
- the new browser window should be scriptable and in the same process as the
- source browser.
-
-
-
-
- Called after a new browser is created.
-
- the ChromiumWebBrowser control
- The browser instance
-
-
-
- Called when a browser has recieved a request to close. This may result
- directly from a call to CefBrowserHost::CloseBrowser() or indirectly if the
- browser is a top-level OS window created by CEF and the user attempts to
- close the window. This method will be called after the JavaScript
- 'onunload' event has been fired. It will not be called for browsers after
- the associated OS window has been destroyed (for those browsers it is no
- longer possible to cancel the close).
-
- If CEF created an OS window for the browser returning false will send an OS
- close notification to the browser window's top-level owner (e.g. WM_CLOSE
- on Windows, performClose: on OS-X and "delete_event" on Linux). If no OS
- window exists (window rendering disabled) returning false will cause the
- browser object to be destroyed immediately. Return true if the browser is
- parented to another window and that other window needs to receive close
- notification via some non-standard technique.
-
- If an application provides its own top-level window it should handle OS
- close notifications by calling CefBrowserHost::CloseBrowser(false) instead
- of immediately closing (see the example below). This gives CEF an
- opportunity to process the 'onbeforeunload' event and optionally cancel the
- close before DoClose() is called.
-
- The CefLifeSpanHandler::OnBeforeClose() method will be called immediately
- before the browser object is destroyed. The application should only exit
- after OnBeforeClose() has been called for all existing browsers.
-
- If the browser represents a modal window and a custom modal loop
- implementation was provided in CefLifeSpanHandler::RunModal() this callback
- should be used to restore the opener window to a usable state.
-
- By way of example consider what should happen during window close when the
- browser is parented to an application-provided top-level OS window.
- 1. User clicks the window close button which sends an OS close
- notification (e.g. WM_CLOSE on Windows, performClose: on OS-X and
- "delete_event" on Linux).
- 2. Application's top-level window receives the close notification and:
- A. Calls CefBrowserHost::CloseBrowser(false).
- B. Cancels the window close.
- 3. JavaScript 'onbeforeunload' handler executes and shows the close
- confirmation dialog (which can be overridden via
- CefJSDialogHandler::OnBeforeUnloadDialog()).
- 4. User approves the close.
- 5. JavaScript 'onunload' handler executes.
- 6. Application's DoClose() handler is called. Application will:
- A. Set a flag to indicate that the next close attempt will be allowed.
- B. Return false.
- 7. CEF sends an OS close notification.
- 8. Application's top-level window receives the OS close notification and
- allows the window to close based on the flag from #6B.
- 9. Browser OS window is destroyed.
- 10. Application's CefLifeSpanHandler::OnBeforeClose() handler is called and
- the browser object is destroyed.
- 11. Application exits by calling CefQuitMessageLoop() if no other browsers
- exist.
-
- the ChromiumWebBrowser control
- The browser instance - check if IsDisposed as it's possible when the browser is disposing
- For default behaviour return false
-
-
-
- Called before a CefBrowser window (either the main browser for ,
- or one of its children)
-
- the ChromiumWebBrowser control
- The browser instance
-
-
-
- Implement this interface to handle events related to browser load status.
- The methods of this interface will be called on the CEF UI thread. Blocking in these methods
- will likely cause your UI to become unresponsive and/or hang.
-
-
-
-
- Called when the loading state has changed. This callback will be executed twice
- once when loading is initiated either programmatically or by user action,
- and once when loading is terminated due to completion, cancellation of failure.
- This method will be called on the CEF UI thread.
- Blocking this thread will likely cause your UI to become unresponsive and/or hang.
-
- the ChromiumWebBrowser control
- args
-
-
-
- Called when the browser begins loading a frame.
- The value will never be empty
- Check the method to see if this frame is the main frame.
- Multiple frames may be loading at the same time. Sub-frames may start or continue loading after the main frame load has ended.
- This method may not be called for a particular frame if the load request for that frame fails.
- For notification of overall browser load status use instead.
- This method will be called on the CEF UI thread.
- Blocking this thread will likely cause your UI to become unresponsive and/or hang.
-
- the ChromiumWebBrowser control
- args
- Whilst thist may seem like a logical place to execute js, it's called before the DOM has been loaded, implement
- as it's called when the underlying V8Context is created
- (Only called for the main frame at this stage)
-
-
-
- Called when the browser is done loading a frame.
- The value will never be empty
- Check the method to see if this frame is the main frame.
- Multiple frames may be loading at the same time. Sub-frames may start or continue loading after the main frame load has ended.
- This method will always be called for all frames irrespective of whether the request completes successfully.
- This method will be called on the CEF UI thread.
- Blocking this thread will likely cause your UI to become unresponsive and/or hang.
-
- the ChromiumWebBrowser control
- args
-
-
-
- Called when the resource load for a navigation fails or is canceled.
- is the error code number, is the error text and
- is the URL that failed to load. See net\base\net_error_list.h
- for complete descriptions of the error codes.
- This method will be called on the CEF UI thread.
- Blocking this thread will likely cause your UI to become unresponsive and/or hang.
-
- the ChromiumWebBrowser control
- args
-
-
-
- Messages sent by the render process can be handled by implementing this
- interface.
-
-
-
-
- OnContextCreated is called in the Render process immediately after a CefV8Context is created.
- An IPC message is immediately sent to notify the context has been created (should be safe to execute javascript).
- If the page has no javascript then no V8Context will be created and as a result this method will not be called.
- Called for every V8Context. To determine if V8Context is from Main frame check
-
- The ChromiumWebBrowser control
- The browser object
- The frame.
-
-
-
- OnContextReleased is called in the Render process immediately before the CefV8Context is released.
- An IPC message is immediately sent to notify the context has been released (cannot execute javascript this point).
- If the page had no javascript then the context would not have been created and as a result this method will not be called.
- Called for every V8Context. To determine if V8Context is from Main frame check
-
- The ChromiumWebBrowser control
- The browser object
- The frame.
-
-
-
- Invoked when an element in the UI gains focus (or possibly no
- element gains focus; i.e. an element lost focus).
-
- The ChromiumWebBrowser control
- The browser object
- The frame object
- An object with information about the node (if any) that has focus.
-
-
-
- OnUncaughtException is called for global uncaught exceptions in a frame. Execution of this callback is disabled by default.
- To enable set CefSettings.UncaughtExceptionStackSize > 0.
-
- The ChromiumWebBrowser control
- The browser object
- The frame
- The exception object with the message and stacktrace.
-
-
-
- Implement this interface to provide handler implementations. The handler
- instance will not be released until all objects related to the context have
- been destroyed. Implement this interface to cancel loading of specific plugins
-
-
-
-
- Called on the browser process IO thread to retrieve the cookie manager. If
- this method returns NULL the default cookie manager retrievable via
- IRequestContext.GetDefaultCookieManager() will be used.
-
- If
- this method returns null the default cookie manager retrievable via
- IRequestContext.GetDefaultCookieManager() will be used..
-
-
-
- Called on the CEF IO thread before a plugin instance is loaded.
- The default plugin policy can be set at runtime using the `--plugin-policy=[allow|detect|block]` command-line flag.
-
- is the mime type of the plugin that will be loaded
- is the content URL that the plugin will load and may be empty
- will be true if the plugin is being loaded in the main (top-level) frame
- is the URL for the top-level frame that contains the plugin
- includes additional information about the plugin that will be loaded
- Modify and return true to change the policy.
- Return false to use the recommended policy. Modify and return true to change the policy.
-
-
-
- Called immediately after the request context has been initialized.
- It's important to note this event is fired on a CEF UI thread, which by default is not the same as your application UI
- thread.
-
- the request context
-
-
-
- Implement this interface to handle events related to browser requests.
- The methods of this class will be called on the thread indicated.
-
-
-
-
- Called before browser navigation.
- If the navigation is allowed and
- will be called. If the navigation is canceled will be called with an ErrorCode
- value of .
-
- the ChromiumWebBrowser control
- the browser object
- The frame the request is coming from
- the request object - cannot be modified in this callback
- The value will be true if the browser navigated via explicit user gesture
- (e.g. clicking a link) or false if it navigated automatically (e.g. via the DomContentLoaded event).
- has the request been redirected
- Return true to cancel the navigation or false to allow the navigation to proceed.
-
-
-
- Called on the UI thread before OnBeforeBrowse in certain limited cases
- where navigating a new or different browser might be desirable. This
- includes user-initiated navigation that might open in a special way (e.g.
- links clicked via middle-click or ctrl + left-click) and certain types of
- cross-origin navigation initiated from the renderer process (e.g.
- navigating the top-level frame to/from a file URL).
-
- the ChromiumWebBrowser control
- the browser object
- The frame object
- target url
- The value indicates where the user intended to navigate the browser based
- on standard Chromium behaviors (e.g. current tab, new tab, etc).
- The value will be true if the browser navigated via explicit user gesture
- (e.g. clicking a link) or false if it navigated automatically (e.g. via the DomContentLoaded event).
- Return true to cancel the navigation or false to allow the navigation
- to proceed in the source browser's top-level frame.
-
-
-
- Called to handle requests for URLs with an invalid SSL certificate.
- Return true and call either
- in this method or at a later time to continue or cancel the request.
- If CefSettings.IgnoreCertificateErrors is set all invalid certificates
- will be accepted without calling this method.
-
- the ChromiumWebBrowser control
- the browser object
- the error code for this invalid certificate
- the url of the request for the invalid certificate
- ssl certificate information
- Callback interface used for asynchronous continuation of url requests.
- If empty the error cannot be recovered from and the request will be canceled automatically.
- Return false to cancel the request immediately. Return true and use to
- execute in an async fashion.
-
-
-
- Called when a plugin has crashed
-
- the ChromiumWebBrowser control
- the browser object
- path of the plugin that crashed
-
-
-
- Called before a resource request is loaded. For async processing return
- and execute or
-
- The ChromiumWebBrowser control
- the browser object
- The frame object
- the request object - can be modified in this callback.
- Callback interface used for asynchronous continuation of url requests.
- To cancel loading of the resource return
- or to allow the resource to load normally. For async
- return
-
-
-
- Called when the browser needs credentials from the user.
-
- The ChromiumWebBrowser control
- the browser object
- The frame object that needs credentials (This will contain the URL that is being requested.)
- indicates whether the host is a proxy server
- hostname
- port number
- realm
- scheme
- Callback interface used for asynchronous continuation of authentication requests.
- Return true to continue the request and call CefAuthCallback::Continue() when the authentication information is available. Return false to cancel the request.
-
-
-
- Called when the browser needs user to select Client Certificate for authentication requests (eg. PKI authentication).
-
- The ChromiumWebBrowser control
- the browser object
- indicates whether the host is a proxy server
- hostname
- port number
- List of Client certificates for selection
- Callback interface used for asynchronous continuation of client certificate selection for authentication requests.
- Return true to continue the request and call ISelectClientCertificateCallback.Select() with the selected certificate for authentication.
- Return false to use the default behavior where the browser selects the first certificate from the list.
-
-
-
- Called when the render process terminates unexpectedly.
-
- The ChromiumWebBrowser control
- the browser object
- indicates how the process terminated.
-
-
-
- Called on the CEF IO thread before sending a network request with a "Cookie"
- request header.
-
- The ChromiumWebBrowser control
- the browser object
- The frame object
- the request object - cannot be modified in this callback
- Return true to allow cookies to be included in the network
- request or false to block cookies
-
-
-
- Called on the CEF IO thread when receiving a network request with a
- "Set-Cookie" response header value represented by cookie.
-
- The ChromiumWebBrowser control
- the browser object
- The frame object
- the request object - cannot be modified in this callback
- the cookie object
- Return true to allow the cookie to be stored or false to block the cookie.
-
-
-
- Called when JavaScript requests a specific storage quota size via the webkitStorageInfo.requestQuota function.
- For async processing return true and execute at a later time to
- grant or deny the request or to cancel.
-
- The ChromiumWebBrowser control
- the browser object
- the origin of the page making the request
- is the requested quota size in bytes
- Callback interface used for asynchronous continuation of url requests.
- Return false to cancel the request immediately. Return true to continue the request
- and call either in this method or at a later time to
- grant or deny the request.
-
-
-
- Called on the IO thread when a resource load is redirected. The
- parameter will contain the old URL and other request-related information.
-
- The ChromiumWebBrowser control
- the browser object
- The frame that is being redirected.
- the request object - cannot be modified in this callback
- the response object
- the new URL and can be changed if desired
-
-
-
- Called on the UI thread to handle requests for URLs with an unknown protocol component.
- SECURITY WARNING: YOU SHOULD USE THIS METHOD TO ENFORCE RESTRICTIONS BASED ON SCHEME, HOST OR OTHER URL ANALYSIS BEFORE ALLOWING OS EXECUTION.
-
- The ChromiumWebBrowser control
- the browser object
- the request url
- return to true to attempt execution via the registered OS protocol handler, if any. Otherwise return false.
-
-
-
- Called on the CEF UI thread when the render view associated
- with browser is ready to receive/handle IPC messages in the render
- process.
-
- The ChromiumWebBrowser control
- the browser object
-
-
-
- Called on the CEF IO thread when a resource response is received.
- To allow the resource to load normally return false.
- To redirect or retry the resource modify request (url, headers or post body) and return true.
- The response object cannot be modified in this callback.
-
- The ChromiumWebBrowser control
- the browser object
- The frame that is being redirected.
- the request object
- the response object - cannot be modified in this callback
-
- To allow the resource to load normally return false.
- To redirect or retry the resource modify request (url, headers or post body) and return true.
-
-
-
-
- Called on the CEF IO thread to optionally filter resource response content.
-
- The ChromiumWebBrowser control
- the browser object
- The frame that is being redirected.
- the request object - cannot be modified in this callback
- the response object - cannot be modified in this callback
- Return an IResponseFilter to intercept this response, otherwise return null
-
-
-
- Called on the CEF IO thread when a resource load has completed.
-
- The ChromiumWebBrowser control
- the browser object
- The frame that is being redirected.
- the request object - cannot be modified in this callback
- the response object - cannot be modified in this callback
- indicates the load completion status
- is the number of response bytes actually read.
-
-
-
- Class used to implement a custom resource handler. The methods of this class will always be called on the CEF IO thread.
- Blocking the CEF IO thread will adversely affect browser performance. We suggest you execute your code in a Task (or similar).
- To implement async handling, spawn a new Task (or similar), keep a reference to the callback. When you have a
- fully populated stream, execute the callback. Once the callback Executes, GetResponseHeaders will be called where you
- can modify the response including headers, or even redirect to a new Url. Set your responseLength and headers
- Populate the dataOut stream in ReadResponse. For those looking for a sample implementation or upgrading from
- a previous version . For those upgrading, inherit from ResourceHandler instead of IResourceHandler
- add the override keywoard to existing methods e.g. ProcessRequestAsync.
-
-
-
-
- Begin processing the request.
-
- The request object.
- The callback used to Continue or Cancel the request (async).
- To handle the request return true and call
- once the response header information is available
- can also be called from inside this method if
- header information is available immediately).
- To cancel the request return false.
-
-
-
- Retrieve response header information. If the response length is not known
- set responseLength to -1 and ReadResponse() will be called until it
- returns false. If the response length is known set responseLength
- to a positive value and ReadResponse() will be called until it returns
- false or the specified number of bytes have been read.
- If an error occured while setting up the request you can set
- to indicate the error condition.
-
- Use the response object to set the mime type, http status code and other optional header values.
- If the response length is not known set responseLength to -1
- To redirect the request to a new URL set redirectUrl to the new Url.
-
-
-
- Read response data. If data is available immediately copy to
- dataOut, set bytesRead to the number of bytes copied, and return true.
- To read the data at a later time set bytesRead to 0, return true and call ICallback.Continue() when the
- data is available. To indicate response completion return false.
-
- Stream to write to
- Number of bytes copied to the stream
- The callback used to Continue or Cancel the request (async).
- If data is available immediately copy to dataOut, set bytesRead to the number of bytes copied,
- and return true.To indicate response completion return false.
- Depending on this size of your response this method may be called multiple times
-
-
-
- Return true if the specified cookie can be sent with the request or false
- otherwise. If false is returned for any cookie then no cookies will be sent
- with the request.
-
- cookie
- Return true if the specified cookie can be sent with the request or false
- otherwise. If false is returned for any cookie then no cookies will be sent
- with the request.
-
-
-
- Return true if the specified cookie returned with the response can be set or false otherwise.
-
- cookie
- Return true if the specified cookie returned with the response can be set or false otherwise.
-
-
-
- Request processing has been canceled.
-
-
-
-
- Interface representing browser initialization settings.
-
-
-
-
- StandardFontFamily
-
-
-
-
- FixedFontFamily
-
-
-
-
- SerifFontFamily
-
-
-
-
- SansSerifFontFamily
-
-
-
-
- CursiveFontFamily
-
-
-
-
- FantasyFontFamily
-
-
-
-
- DefaultFontSize
-
-
-
-
- DefaultFixedFontSize
-
-
-
-
- MinimumFontSize
-
-
-
-
- MinimumLogicalFontSize
-
-
-
-
- Default encoding for Web content. If empty "ISO-8859-1" will be used. Also
- configurable using the "default-encoding" command-line switch.
-
-
-
-
- Controls the loading of fonts from remote sources. Also configurable using
- the "disable-remote-fonts" command-line switch.
-
-
-
-
- Controls whether JavaScript can be executed. (Used to Enable/Disable javascript)
- Also configurable using the "disable-javascript" command-line switch.
-
-
-
-
- Controls whether JavaScript can be used to close windows that were not
- opened via JavaScript. JavaScript can still be used to close windows that
- were opened via JavaScript. Also configurable using the
- "disable-javascript-close-windows" command-line switch.
-
-
-
-
- Controls whether JavaScript can access the clipboard. Also configurable
- using the "disable-javascript-access-clipboard" command-line switch.
-
-
-
-
- Controls whether DOM pasting is supported in the editor via
- execCommand("paste"). The |javascript_access_clipboard| setting must also
- be enabled. Also configurable using the "disable-javascript-dom-paste"
- command-line switch.
-
-
-
-
- Controls whether any plugins will be loaded. Also configurable using the
- "disable-plugins" command-line switch.
-
-
-
-
- Controls whether file URLs will have access to all URLs. Also configurable
- using the "allow-universal-access-from-files" command-line switch.
-
-
-
-
- Controls whether file URLs will have access to other file URLs. Also
- configurable using the "allow-access-from-files" command-line switch.
-
-
-
-
- Controls whether web security restrictions (same-origin policy) will be
- enforced. Disabling this setting is not recommend as it will allow risky
- security behavior such as cross-site scripting (XSS). Also configurable
- using the "disable-web-security" command-line switch.
-
-
-
-
- Controls whether image URLs will be loaded from the network. A cached image
- will still be rendered if requested. Also configurable using the
- "disable-image-loading" command-line switch.
-
-
-
-
- Controls whether standalone images will be shrunk to fit the page. Also
- configurable using the "image-shrink-standalone-to-fit" command-line
- switch.
-
-
-
-
- Controls whether text areas can be resized. Also configurable using the
- "disable-text-area-resize" command-line switch.
-
-
-
-
- Controls whether the tab key can advance focus to links. Also configurable
- using the "disable-tab-to-links" command-line switch.
-
-
-
-
- Controls whether local storage can be used. Also configurable using the
- "disable-local-storage" command-line switch.
-
-
-
-
- Controls whether databases can be used. Also configurable using the
- "disable-databases" command-line switch.
-
-
-
-
- Controls whether the application cache can be used. Also configurable using
- the "disable-application-cache" command-line switch.
-
-
-
-
- Controls whether WebGL can be used. Note that WebGL requires hardware
- support and may not work on all systems even when enabled. Also
- configurable using the "disable-webgl" command-line switch.
-
-
-
-
- Opaque background color used for the browser before a document is loaded
- and when no document color is specified. By default the background color
- will be the same as CefSettings.BackgroundColor. Only the RGB compontents
- of the specified value will be used. The alpha component must greater than
- 0 to enable use of the background color but will be otherwise ignored.
-
-
-
-
- Comma delimited ordered list of language codes without any whitespace that
- will be used in the "Accept-Language" HTTP header. May be overridden on a
- per-browser basis using the CefBrowserSettings.AcceptLanguageList value.
- If both values are empty then "en-US,en" will be used. Can be overridden
- for individual RequestContext instances via the
- RequestContextSettings.AcceptLanguageList value.
-
-
-
-
- The maximum rate in frames per second (fps) that CefRenderHandler::OnPaint
- will be called for a windowless browser. The actual fps may be lower if
- the browser cannot generate frames at the requested rate. The minimum
- value is 1 and the maximum value is 60 (default 30). This value can also be
- changed dynamically via IBrowserHost.SetWindowlessFrameRate.
-
-
-
-
- Gets a value indicating if the browser settings has been disposed.
-
-
-
-
- Represents the tag name and attribute data belonging to a node in the
- browser's DOM.
-
-
-
-
- Get the value of an attribute.
-
-
- The name of the attribute value to get.
-
-
- The attribute value if the name exists in the DomNode's attributes.
- Null if the name does not exist.
-
-
-
-
- The name of the HTML element.
-
-
-
-
- Get a read only list of the attribute names.
-
-
-
-
- Determine if the DomNode has the requested attribute.
-
-
- The name of the attribute value.
-
-
- True if the attribute exists in the DomNode, false if it does not.
-
-
-
-
- Class representing popup window features.
-
-
-
-
- A request context provides request handling for a set of related browser or URL request objects.
- A request context can be specified when creating a new browser by setting the
- property (Passing in via the constructor for the OffScreen
- control is preferred).
- Browser objects with different request contexts will never be hosted in the same render process.
- Browser objects with the same request context may or may not be hosted in the same render process
- depending on the process model.Browser objects created indirectly via the JavaScript window.open
- function or targeted links will share the same render process and the same request context as
- the source browser.
-
-
-
-
- Returns true if this object is pointing to the same context object.
-
- context to compare
- Returns true if the same
-
-
-
- Returns true if this object is sharing the same storage as the specified context.
-
- context to compare
- Returns true if same storage
-
-
-
- Returns true if this object is the global context. The global context is
- used by default when creating a browser or URL request with a NULL context
- argument.
-
-
-
-
- Returns the default cookie manager for this object. This will be the global
- cookie manager if this object is the global request context. Otherwise,
- this will be the default cookie manager used when this request context does
- not receive a value via IRequestContextHandler.GetCookieManager().
-
- If callback is non-NULL it will be executed asnychronously on the CEF IO thread
- after the manager's storage has been initialized.
- Returns the default cookie manager for this object
-
-
-
- Register a scheme handler factory for the specified schemeName and optional domainName.
- An empty domainName value for a standard scheme will cause the factory to match all domain
- names. The domainName value will be ignored for non-standard schemes. If schemeName is
- a built-in scheme and no handler is returned by factory then the built-in scheme handler
- factory will be called. If schemeName is a custom scheme then you must also implement the
- CefApp::OnRegisterCustomSchemes() method in all processes. This function may be called multiple
- times to change or remove the factory that matches the specified schemeName and optional
- domainName.
-
- Scheme Name
- Optional domain name
- Scheme handler factory
- Returns false if an error occurs.
-
-
-
- Clear all registered scheme handler factories.
-
- Returns false on error.
-
-
-
- Returns the cache path for this object. If empty an "incognito mode"
- in-memory cache is being used.
-
-
-
-
- Tells all renderer processes associated with this context to throw away
- their plugin list cache. If reloadPages is true they will also reload
- all pages with plugins. RequestContextHandler.OnBeforePluginLoad may
- be called to rebuild the plugin list cache.
-
- reload any pages with pluginst
-
-
-
- Returns true if a preference with the specified name exists. This method
- must be called on the CEF UI thread.
-
- name of preference
- bool if the preference exists
- Use Cef.UIThreadTaskFactory to execute this method if required,
- and ChromiumWebBrowser.IsBrowserInitializedChanged are both
- executed on the CEF UI thread, so can be called directly.
- When CefSettings.MultiThreadedMessageLoop == false (the default is true) then the main
- application thread will be the CEF UI thread.
-
-
-
- Returns the value for the preference with the specified name. Returns
- NULL if the preference does not exist. The returned object contains a copy
- of the underlying preference value and modifications to the returned object
- will not modify the underlying preference value. This method must be called
- on the CEF UI thread.
-
- preference name
- Returns the value for the preference with the specified name
- Use Cef.UIThreadTaskFactory to execute this method if required,
- and ChromiumWebBrowser.IsBrowserInitializedChanged are both
- executed on the CEF UI thread, so can be called directly.
- When CefSettings.MultiThreadedMessageLoop == false (the default is true) then the main
- application thread will be the CEF UI thread.
-
-
-
- Returns all preferences as a dictionary. The returned
- object contains a copy of the underlying preference values and
- modifications to the returned object will not modify the underlying
- preference values. This method must be called on the browser process UI
- thread.
-
- If true then
- preferences currently at their default value will be included.
- Preferences (dictionary can have sub dictionaries)
-
-
-
- Returns true if the preference with the specified name can be modified
- using SetPreference. As one example preferences set via the command-line
- usually cannot be modified. This method must be called on the CEF UI thread.
-
- preference key
- Returns true if the preference with the specified name can be modified
- using SetPreference
- Use Cef.UIThreadTaskFactory to execute this method if required,
- and ChromiumWebBrowser.IsBrowserInitializedChanged are both
- executed on the CEF UI thread, so can be called directly.
- When CefSettings.MultiThreadedMessageLoop == false (the default is true) then the main
- application thread will be the CEF UI thread.
-
-
-
- Set the value associated with preference name. If value is null the
- preference will be restored to its default value. If setting the preference
- fails then error will be populated with a detailed description of the
- problem. This method must be called on the CEF UI thread.
- Preferences set via the command-line usually cannot be modified.
-
- preference key
- preference value
- out error
- Returns true if the value is set successfully and false otherwise.
- Use Cef.UIThreadTaskFactory to execute this method if required,
- and ChromiumWebBrowser.IsBrowserInitializedChanged are both
- executed on the CEF UI thread, so can be called directly.
- When CefSettings.MultiThreadedMessageLoop == false (the default is true) then the main
- application thread will be the CEF UI thread.
-
-
-
- Clears all certificate exceptions that were added as part of handling
- . If you call this it is
- recommended that you also call or you risk not
- being prompted again for server certificates if you reconnect quickly.
-
- If is non-NULL it will be executed on the CEF UI thread after
- completion. This param is optional
-
-
-
- Clears all active and idle connections that Chromium currently has.
- This is only recommended if you have released all other CEF objects but
- don't yet want to call Cef.Shutdown().
-
- If is non-NULL it will be executed on the CEF UI thread after
- completion. This param is optional
-
-
-
- Attempts to resolve origin to a list of associated IP addresses.
-
- host name to resolve
- A task that represents the Resoolve Host operation. The value of the TResult parameter contains ResolveCallbackResult.
-
-
-
- Attempts to resolve origin to a list of associated IP addresses using
- cached data. This method must be called on the CEF IO thread. Use
- Cef.IOThreadTaskFactory to execute on that thread.
-
- host name to resolve
- list of resolved IP
- addresses or empty list if no cached data is available.
- Returns on success
-
-
-
- Returns true if this context was used to load the extension identified by extensionId. Other contexts sharing the same storage will also have access to the extension (see HasExtension).
- This method must be called on the CEF UI thread.
-
- Returns true if this context was used to load the extension identified by extensionId
-
-
-
- Returns the extension matching extensionId or null if no matching extension is accessible in this context (see HasExtension).
- This method must be called on the CEF UI thread.
-
- extension Id
- Returns the extension matching extensionId or null if no matching extension is accessible in this context
-
-
-
- Retrieve the list of all extensions that this context has access to (see HasExtension).
- will be populated with the list of extension ID values.
- This method must be called on the CEF UI thread.
-
- output a list of extensions Ids
- returns true on success otherwise false
-
-
-
- Returns true if this context has access to the extension identified by extensionId.
- This may not be the context that was used to load the extension (see DidLoadExtension).
- This method must be called on the CEF UI thread.
-
- extension id
- Returns true if this context has access to the extension identified by extensionId
-
-
-
- Load an extension. If extension resources will be read from disk using the default load implementation then rootDirectoy
- should be the absolute path to the extension resources directory and manifestJson should be null.
- If extension resources will be provided by the client (e.g. via IRequestHandler and/or IExtensionHandler) then rootDirectory
- should be a path component unique to the extension (if not absolute this will be internally prefixed with the PK_DIR_RESOURCES path)
- and manifestJson should contain the contents that would otherwise be read from the "manifest.json" file on disk.
- The loaded extension will be accessible in all contexts sharing the same storage (HasExtension returns true).
- However, only the context on which this method was called is considered the loader (DidLoadExtension returns true) and only the
- loader will receive IRequestContextHandler callbacks for the extension.
-
- will be called on load success or
- will be called on load failure.
-
- If the extension specifies a background script via the "background" manifest key then
- will be called to create the background browser. See that method for additional information about background scripts.
-
- For visible extension views the client application should evaluate the manifest to determine the correct extension URL to load and then
- load the extension URL in a ChromiumWebBrowser instance after the extension has loaded.
-
- For example, the client can look for the "browser_action" manifest key as documented at https://developer.chrome.com/extensions/browserAction.
- Extension URLs take the form "chrome-extension://<extension_id>/<path>"
- Browsers that host extensions differ from normal browsers as follows:
-
- - Can access chrome.* JavaScript APIs if allowed by the manifest. Visit chrome://extensions-support for the list of extension APIs currently supported by CEF.
- - Main frame navigation to non-extension content is blocked.
- - Pinch-zooming is disabled.
- - returns the hosted extension.
- - CefBrowserHost::IsBackgroundHost returns true for background hosts.
-
- See https://developer.chrome.com/extensions for extension implementation and usage documentation.
-
- If extension resources will be read from disk using the default load implementation then rootDirectoy
- should be the absolute path to the extension resources directory and manifestJson should be null
- If extension resources will be provided by the client then rootDirectory should be a path component unique to the extension
- and manifestJson should contain the contents that would otherwise be read from the manifest.json file on disk
- handle events related to browser extensions
-
- For extensions that load a popup you are required to query the Manifest, build a Url in the format
- chrome-extension://{extension.Identifier}/{default_popup} with default_popup url coming from the mainfest. With the extension
- url you then need to open a new Form/Window/Tab and create a new ChromiumWebBrowser instance to host the extension popup.
- To load a crx file you must first unzip them to a folder and pass the path containing the extension as .
- It in theory should be possible to load a crx file in memory, passing it's manifest.json file content as
- then fulfilling the resource rquests made to .
-
-
-
-
- Implement this interface to filter resource response content.
- The methods of this class will be called on the CEF IO thread.
-
-
-
-
- Initialize the response filter. Will only be called a single time.
- The filter will not be installed if this method returns false.
-
- The filter will not be installed if this method returns false.
-
-
-
- Called to filter a chunk of data.
- This method will be called repeatedly until there is no more data to filter (resource response is complete),
- dataInRead matches dataIn.Length (all available pre-filter bytes have been read), and the method
- returns FilterStatus.Done or FilterStatus.Error.
-
- is a Stream wrapping the underlying input buffer containing pre-filter data. Can be null.
- Set to the number of bytes that were read from dataIn
- is a Stream wrapping the underlying output buffer that can accept filtered output data.
- Check dataOut.Length for maximum buffer size
- Set to the number of bytes that were written into dataOut
- If some or all of the pre-filter data was read successfully but more data is needed in order
- to continue filtering (filtered output is pending) return FilterStatus.NeedMoreData. If some or all of the pre-filter
- data was read successfully and all available filtered output has been written return FilterStatus.Done. If an error
- occurs during filtering return FilterStatus.Error.
- Do not keep a reference to the buffers(Streams) passed to this method.
-
-
-
- Model binding context object
-
-
-
-
- Binding destination type
-
-
-
-
- The generic type of a collection is only used when DestinationType is a enumerable.
-
-
-
-
- The current model object (or null for body deserialization)
-
-
-
-
- DestinationType properties that are not black listed
-
-
-
-
- The incoming data fields
-
-
-
-
- Represents a bindable member of a type, which can be a property or a field.
-
-
-
-
- Gets a reference to the MemberInfo that this BindingMemberInfo represents. This can be a property or a field.
-
-
-
-
- Gets the name of the property or field represented by this BindingMemberInfo.
-
-
-
-
- Gets the data type of the property or field represented by this BindingMemberInfo.
-
-
-
-
- Constructs a BindingMemberInfo instance for a property.
-
- The bindable property to represent.
-
-
-
- Constructs a BindingMemberInfo instance for a field.
-
- The bindable field to represent.
-
-
-
- Sets the value from a specified object associated with the property or field represented by this BindingMemberInfo.
-
- The object whose property or field should be assigned.
- The value to assign in the specified object to this BindingMemberInfo's property or field.
-
-
-
-
-
-
- Compares two BindingMemberInfo's with eachother on their respective values rather then their reference
-
- the other BindingMemberInfo
- true when they are equal and false otherwise
-
-
-
-
-
-
- Returns an enumerable sequence of bindable properties for the specified type.
-
- The type to enumerate.
- Bindable properties.
-
-
-
- Returns an enumerable sequence of bindable properties for the specified type.
-
- The type to enumerate.
- Bindable properties.
-
-
-
- Default binder - used as a fallback when a specific modelbinder
- is not available.
-
-
-
-
- List of property names to be ignored
-
-
-
-
- DefaultBinder constructor
-
- used to convert field names to property names
-
-
-
- Bind to the given model type
-
- object to be converted into a model
- Model type to bind to
- Bound model
-
-
-
- CreateBindingContext - Can be overriden to change some binding context features
-
- object
- model type
- generic type
- binding context
-
-
-
- BindValue
-
- model property
- object
- context
-
-
-
- Get binding members
-
- model type
- generic type
- collection of binding member informations
-
-
-
- Create model based on type
-
- model type
- generic type
- a new instance of the object type
-
-
-
- Gets the value for the property name
-
- property name
- context
- value or null
-
-
-
- Gets the value based on the index, used to accessing objects
- in a collection.
-
- binding context
- index
- element or null
-
-
-
- Default field name converter
- Converts camel case to pascal case
-
-
-
-
- Initializes a new instance of the class.
-
-
-
-
- Converts a field name to a property name
-
- Field name
- Property name
-
-
-
- Provides the capability intercept Net method calls made from javascript as part of the
- JavascriptBinding (JSB) implementation. One example use case is logging method calls.
-
-
-
-
- Called before the method is invokved. You are now responsible for evaluating
- the function and returning the result.
-
- A Func that represents the method to be called
- Name of the method to be called
- The method result
-
- object IMethodInterceptor.Intercept(Func<object> method, string methodName)
- {
- object result = method();
- Debug.WriteLine("Called " + methodName);
- return result;
- }
-
-
-
-
- Binds incoming request data to a model type
-
-
-
-
- Bind to the given model type
-
- object to be converted into a model
- Model type to bind to
- Bound model
-
-
-
- Provides the capability to supply a convention to
- convert form field names to property names if required.
-
-
-
-
- Converts a field name to a property name
-
- Field name
- Property name
-
-
-
- Containing extensions for the object.
-
-
-
-
- Checks if a type is an array or not
-
- The type to check.
- if the type is an array, otherwise .
-
-
-
- Checks if a type is an collection or not
-
- The type to check.
- if the type is a collection, otherwise .
-
-
-
- Checks if a type is enumerable or not
-
- The type to check.
- if the type is an enumerable, otherwise .
-
-
-
- Represents an entry in navigation history.
-
-
-
-
- Returns the time for the last known successful navigation completion.
-
-
-
-
- Returns a display-friendly version of the URL.
-
-
-
-
- Returns the HTTP status code for the last known successful navigation response.
-
-
-
-
- Returns the original URL that was entered by the user before any redirects.
-
-
-
-
- Returns the title set by the page.
-
-
-
-
- Returns the transition type which indicates what the user did to move to this page from the previous page.
-
-
-
-
- Returns the actual URL of the page.
-
-
-
-
- Returns true if this navigation includes post data.
-
-
-
-
- Returns true if this object is valid.
-
-
-
-
- If true if this entry is the currently loaded navigation entry
-
-
-
-
- Returns the SSL information for this navigation entry.
-
-
-
-
- NavigationEntry
-
- completionTime
- displayUrl
- httpStatusCode
- originalUrl
- title
- transitionType
- url
- hasPostData
- isValid
- is the current entry
- the ssl status
-
-
-
- Print to Pdf Settings
-
-
-
-
- Page title to display in the header. Only used if
- is set to true.
-
-
-
-
- URL to display in the footer. Only used if is set
- to true.
-
-
-
-
- Output page size in microns. If either of these values is less than or
- equal to zero then the default paper size (A4) will be used.
-
-
-
-
- Output page size in microns. If either of these values is less than or
- equal to zero then the default paper size (A4) will be used.
-
-
-
-
- Margin in millimeters. Only used if MarginType is set to Custom.
-
-
-
-
- Margin in millimeters. Only used if MarginType is set to Custom.
-
-
-
-
- Margin in millimeters. Only used if MarginType is set to Custom.
-
-
-
-
- Margin in millimeters. Only used if MarginType is set to Custom.
-
-
-
-
- Margin type.
-
-
-
-
- Scale the PDF by the specified amount, defaults to 100%.
-
-
-
-
- Set to true to print headers and footers or false to not print
- headers and footers.
-
-
-
-
- Set to true to print the selection only or false to print all.
-
-
-
-
- Set to true for landscape mode or false for portrait mode.
-
-
-
-
- Set to true to print background graphics or false to not print
- background graphics.
-
-
-
-
- Used for managing cookies. The methods may be called on any thread unless otherwise indicated.
-
-
-
-
- Deletes all cookies that matches all the provided parameters. If both and are empty, all cookies will be deleted.
- Cookies can alternately be deleted using the Visit*Cookies() methods.
- This method will be executed on the CEF IO thread in an async fashion, to be notified upon completion implement
- and pass in as
-
- The cookie URL. If an empty string is provided, any URL will be matched.
- The name of the cookie. If an empty string is provided, any URL will be matched.
- If non-NULL it will be executed asnychronously on the CEF IO thread after the cookies have been deleted.
- Returns false if a non-empty invalid URL is specified, or if cookies cannot be accessed; otherwise, true.
-
-
-
- Sets a cookie given a valid URL and explicit user-provided cookie attributes. This function expects each attribute to be well-formed. It will check for disallowed
- characters (e.g. the ';' character is disallowed within the cookie value attribute) and will return false without setting
- the cookie if such characters are found.
- This method will be executed on the CEF IO thread in an async fashion, to be notified upon completion implement
- and pass in as
-
- The cookie URL
- The cookie
- If non-NULL it will be executed asnychronously on the CEF IO thread after the cookie has been set.
- returns false if the cookie cannot be set (e.g. if illegal charecters such as ';' are used); otherwise true.
-
-
-
- Sets the directory path that will be used for storing cookie data. If is empty data will be stored in
- memory only. Otherwise, data will be stored at the specified path. To persist session cookies (cookies without an expiry
- date or validity interval) set to true. Session cookies are generally intended to be transient and
- most Web browsers do not persist them.
-
- The file path to write cookies to.
- A flag that determines whether session cookies will be persisted or not.
- If non-NULL it will be executed asnychronously on the CEF IO thread after the
- manager's storage has been initialized
- Returns false if cookies cannot be accessed
-
-
-
- Set the schemes supported by this manager. By default only "http" and "https" schemes are supported. Must be called before any cookies are accessed.
-
- The list of supported schemes.
- If non-NULL it will be executed asnychronously on the CEF IO thread after the change has been applied.
-
-
-
- Visits all cookies using the provided Cookie Visitor. The returned cookies are sorted by longest path, then by earliest creation date.
-
- A user-provided Cookie Visitor implementation.
- Returns false if cookies cannot be accessed; otherwise, true.
-
-
-
- Visits a subset of the cookies. The results are filtered by the given url scheme, host, domain and path.
- If is true, HTTP-only cookies will also be included in the results. The returned cookies
- are sorted by longest path, then by earliest creation date.
-
- The URL to use for filtering a subset of the cookies available.
- A flag that determines whether HTTP-only cookies will be shown in results.
- A user-provided Cookie Visitor implementation.
- Returns false if cookies cannot be accessed; otherwise, true.
-
-
-
- Flush the backing store (if any) to disk
- This method will be executed on the CEF IO thread in an async fashion, to be notified upon completion implement
- and pass in as
-
- If non-NULL it will be executed asnychronously on the CEF IO thread after the flush is complete.
- Returns false if cookies cannot be accessed.
-
-
-
- Returns true if disposed
-
-
-
-
- Supports creation and modification of menus. See for the command ids that have default implementations.
- All user-defined command ids should be between and .
- The methods of this class can only be accessed on the CEF UI thread, which by default is not the same as your application UI thread.
-
-
-
-
- Returns the number of items in this menu.
-
-
-
-
- Remove all menu items. Can be used to disable the context menu. Returns true on success.
-
- Returns true on success
-
-
-
- Returns the label at the specified index or empty if not found due to
- invalid range or the index being a separator.
-
- specified index
- Label or empty if not found due to invalid range or the index being a separator.
-
-
-
- Returns the command id at the specified index or -1 if not found due to invalid range or the index being a separator.
-
- the index
- Command or -1 if not found due to invalid range or the index being a separator.
-
-
-
- Removes the item with the specified commandId.
-
- the command Id
- Returns true on success
-
-
-
- Add an item to the menu.
-
- the command Id
- the label of the item
- Returns true on success.
-
-
-
- Add a separator to the menu.
-
- Returns true on success.
-
-
-
- Add a check item to the menu.
-
- the command Id
- the label of the item
- Returns true on success.
-
-
-
- Add a radio item to the menu. Only a single item with the specified groupId can be checked at a time.
-
- the command Id
- the label of the item
- the group id
- Returns true on success.
-
-
-
- Add a sub-menu to the menu. The new sub-menu is returned.
-
- the command Id
- the label of the item
- Returns the newly created .
-
-
-
- Insert a separator in the menu at the specified index.
-
- index
- Returns true on success.
-
-
-
- Insert an item in the menu at the specified index.
-
- index
- the command Id
- the label of the item
- Returns true on success.
-
-
-
- Insert a check item in the menu at the specified index.
-
- index
- the command Id
- the label of the item
- Returns true on success.
-
-
-
- Insert a radio item in the menu at the specified index.
- Only a single item with the specified groupId can be checked at a time.
-
- index
- the command Id
- the label of the item
- the group id
- Returns true on success.
-
-
-
- Insert a sub-menu in the menu at the specified index.
-
- index
- the command Id
- the label of the item
- Returns the newly created .
-
-
-
- Removes the item at the specified index.
-
- index
- Returns true on success.
-
-
-
- Returns the index associated with the specified commandId or -1 if not found due to the command id not existing in the menu.
-
- the command Id
- Returns the index associated with the specified commandId or -1 if not found due to the command id not existing in the menu.
-
-
-
- Sets the command id at the specified index.
-
- index
- the command Id
- Returns true on success.
-
-
-
- Returns the label for the specified commandId or empty if not found.
-
- the command Id
- Returns the label for the specified commandId or empty if not found.
-
-
-
- Sets the label for the specified commandId.
-
- the command Id
- the label
- Returns true on success.
-
-
-
- Set the label at the specified index.
-
- index
- the label
- Returns true on success.
-
-
-
- Returns the item type for the specified commandId.
-
- the command Id
- Returns the item type for the specified commandId.
-
-
-
- Returns the item type at the specified index.
-
- index
- Returns the item type at the specified index.
-
-
-
- Returns the group id for the specified commandId or -1 if invalid.
-
- the command Id
- Returns the group id for the specified commandId or -1 if invalid.
-
-
-
- Returns the group id at the specified index or -1 if invalid.
-
- index
- Returns the group id at the specified index or -1 if invalid.
-
-
-
- Sets the group id for the specified commandId.
-
- the command Id
- the group id
- Returns true on success.
-
-
-
- Sets the group id at the specified index.
-
- index
- the group id
- Returns true on success.
-
-
-
- Returns the for the specified commandId or null if invalid.
-
- the command Id
- Returns the for the specified commandId or null if invalid.
-
-
-
- Returns the at the specified index or empty if invalid.
-
- index
- Returns the for the specified commandId or null if invalid.
-
-
-
- Returns true if the specified commandId is visible.
-
- the command Id
- Returns true if the specified commandId is visible.
-
-
-
- Returns true if the specified index is visible.
-
- index
- Returns true if the specified index is visible.
-
-
-
- Change the visibility of the specified commandId.
-
- the command Id
- visible
- Returns true on success.
-
-
-
- Change the visibility at the specified index.
-
- index
- visible
- Returns true on success.
-
-
-
- Returns true if the specified commandId is enabled.
-
- the command Id
- Returns true if the specified commandId is enabled.
-
-
-
- Returns true if the specified index is enabled.
-
- index
- Returns true if the specified index is enabled.
-
-
-
- Change the enabled status of the specified commandId.
-
- the command Id
- is enabled
- Returns true on success.
-
-
-
- Change the enabled status at the specified index.
-
- index
- is enabled
- Returns true on success.
-
-
-
- Returns true if the specified commandId is checked. Only applies to check and radio items.
-
- the command Id
- Returns true if the specified commandId is checked. Only applies to check and radio items.
-
-
-
- Returns true if the specified index is checked. Only applies to check and radio items.
-
- index
- Returns true if the specified index is checked. Only applies to check and radio items.
-
-
-
- Check the specified commandId. Only applies to check and radio items.
-
- the command Id
- set checked
- Returns true on success.
-
-
-
- Check the specified index. Only applies to check and radio items.
-
- index
- set checked
- Returns true on success.
-
-
-
- Returns true if the specified commandId has a keyboard accelerator assigned.
-
- the command Id
- Returns true if the specified commandId has a keyboard accelerator assigned.
-
-
-
- Returns true if the specified index has a keyboard accelerator assigned.
-
- index
- Returns true if the specified index has a keyboard accelerator assigned.
-
-
-
- Set the keyboard accelerator for the specified commandId.
-
- the command Id
- keyCode can be any key or character value.
- shift key pressed
- ctrl key pressed
- alt key pressed
- Returns true on success.
-
-
-
- Set the keyboard accelerator at the specified index. keyCode can be any key or character value.
-
- index
- keyCode can be any key or character value.
- shift key pressed
- ctrl key pressed
- alt key pressed
- Returns true on success.
-
-
-
- Remove the keyboard accelerator for the specified commandId.
-
- the command Id
- Returns true on success.
-
-
-
- Remove the keyboard accelerator at the specified index.
-
- index
- Returns true on success.
-
-
-
- Retrieves the keyboard accelerator for the specified commandId.
-
- the command Id
- keyCode can be any key or character value.
- shift key pressed
- ctrl key pressed
- alt key pressed
- Returns true on success.
-
-
-
- Retrieves the keyboard accelerator for the specified index.
-
- index
- keyCode can be any key or character value.
- shift key pressed
- ctrl key pressed
- alt key pressed
- Returns true on success.
-
-
-
- Proxy options
-
-
-
-
- The IP address for the proxy
-
-
-
-
- The port for the proxy
-
-
-
-
- The username for authentication
-
-
-
-
- The password for authentication
-
-
-
-
- The list of domains that shouldn't be affected by the proxy, Format: example.com;example2.com
-
-
-
-
- Checks if username and password is set
-
- Returns true if both username and password is set, otherwise false
-
-
- The IP address for the proxy
- The port for the proxy
- The username required for authentication
- The password required for authentication
- The list of domains that shouldn't be affected by the proxy, Format: example.com;example2.com
-
-
-
- Data
-
-
-
-
- Mime Type
-
-
-
-
- Whether or not the handler should be used once (true) or until manually unregistered (false)
-
-
-
-
- DefaultResourceHandlerFactoryItem constructor
-
- The data in byte[] format that will be used for the response
- mime type
- Whether or not the handler should be used once (true) or until manually unregistered (false)
-
-
-
- Class representing SSL information.
-
-
-
-
- Returns a bitmask containing any and all problems verifying the server
- certificate.
-
-
-
-
- Returns the X.509 certificate.
-
-
-
-
- Class representing a a keyboard event.
-
-
-
-
- The type of keyboard event.
-
-
-
-
- Bit flags describing any pressed modifier keys. See
- cef_event_flags_t for values.
-
-
-
-
- The Windows key code for the key event. This value is used by the DOM
- specification. Sometimes it comes directly from the event (i.e. on
- Windows) and sometimes it's determined using a mapping function. See
- WebCore/platform/chromium/KeyboardCodes.h for the list of values.
-
-
-
-
- The actual key code genenerated by the platform.
-
-
-
-
- Indicates whether the event is considered a "system key" event (see
- http://msdn.microsoft.com/en-us/library/ms646286(VS.85).aspx for details).
- This value will always be false on non-Windows platforms.
-
-
-
-
- True if the focus is currently on an editable field on the page. This is useful for determining if standard key events should be intercepted.
-
-
-
-
- Class used to represent post data for a web request. The methods of this class may be called on any thread.
-
-
-
-
- Add the specified .
-
- element to be added.
- Returns true if the add succeeds.
-
-
-
- Remove the specified .
-
- element to be removed.
- Returns true if the add succeeds.
-
-
-
- Retrieve the post data elements.
-
-
-
-
- Returns true if this object is read-only.
-
-
-
-
- Remove all existing post data elements.
-
-
-
-
- Gets a value indicating whether the object has been disposed of.
-
-
-
-
- Create a new instance
-
-
-
-
-
- Returns true if the underlying POST data includes elements that are not
- represented by this IPostData object (for example, multi-part file upload
- data). Modifying IPostData objects with excluded elements may result in
- the request failing.
-
-
-
-
- Class used to represent a single element in the request post data.
- The methods of this class may be called on any thread.
-
-
-
-
- Gets or sets the file name.
-
-
-
-
- Gets if the object is read-only.
-
-
-
-
- Remove all contents from the post data element.
-
-
-
-
- Gets the type of this .
-
-
-
-
- Gets or sets the bytes of this .
-
-
-
-
- Use this static class to configure some CefSharp specific settings like WcfTimeout
-
-
-
-
- Set default values for CefSharpSettings
-
-
-
-
- Objects registered using RegisterJsObject and RegisterAsyncJsObject
- will be automatically bound in the first render process that's created
- for a ChromiumWebBrowser instance. If you perform a cross-site
- navigation a process switch will occur and bound objects will no longer
- be automatically avaliable. For those upgrading from version 57 or below
- that do no perform cross-site navigation (e.g. Single Page applications or
- applications that only refer to a single domain) can set this property to
- true and use the old behaviour.Defaults to false
- NOTE: Set this before your first call to RegisterJsObject or RegisterAsyncJsObject
-
-
- Javascript binding in CefSharp version 57 and below used the
- --process-per-tab Process Model to limit the number of render
- processes to 1 per ChromiumWebBrowser instance, this allowed
- us to communicate bound javascript objects when the process was
- initially created (OnRenderViewReady is only called for the first
- process creation or after a crash), subsiquently all bound objects
- were registered in ever V8Context in OnContextCreated (executed in the render process).
- Chromium has made changes and --process-per-tab is not currently working.
- Performing a cross-site navigation (from one domain to a different domain)
- will cause a new render process to be created, subsiquent render processes
- won't have access to the bound object information by default.
-
-
-
-
- WCF is used by RegisterJsObject feature for Javascript Binding
- It's reccomended that anyone developing a new application use
- the RegisterAsyncJsObject version which communicates using native
- Chromium IPC.
-
-
-
-
- Change the Close timeout for the WCF channel used by the sync JSB binding.
- The default value is currently 2 seconds. Changing this to
- will result on Abort() being called on the WCF Channel Host
-
-
-
-
- For the WinForms and WPF instances of ChromiumWebBrowser the relevant Application Exit event
- is hooked and Cef.Shutdown() called by default. Set this to false to disable this behaviour.
- This value needs to be set before the first instance of ChromiumWebBrowser is created as
- the event handlers are hooked in the static constructor for the ChromiumWebBrowser class
-
-
-
-
- CefSharp.BrowserSubprocess will monitor the parent process and exit if the parent process closes
- before the subprocess. This currently defaults to false.
- See https://github.com/cefsharp/CefSharp/issues/2359 for more information.
-
-
-
-
- The proxy options that will be used for all connections
-
- If set before the call to Cef.Initialize, command line arguments will be set for you
- If a username and password is provided and the IPs match authentication is done automatically
-
- NOTE: GetAuthCredentials won't be called for a proxy server that matches the IP
- NOTE: It isn't possble to change the proxy after the call to Cef.Initialize
-
-
-
-
- This influences the behavior of RegisterAsyncJsObject and how method calls are made.
- By default the executes Tasks in a sync fashion.
- Setting this property to true will allocate new Tasks on TaskScheduler.Default for execution.
-
-
-
-
- If true a message will be sent from the render subprocess to the
- browser when a DOM node (or no node) gets focus. The default is
- false.
-
-
-
-
- Class used to Represent a cookie the built in .Net Cookie
- class isn't used as some of it's properties have internal setters
-
-
-
-
- The cookie name
-
-
-
-
- The cookie value.
-
-
-
-
- If domain is empty a host cookie will be created instead of a domain cookie. Domain cookies are stored with a leading "."
- and are visible to sub-domains whereas host cookies are not.
-
-
-
-
- Ss non-empty only URLs at or below the path will get the cookie value.
-
-
-
-
- If true the cookie will only be sent for HTTPS requests.
-
-
-
-
- Ss true the cookie will only be sent for HTTP requests.
-
-
-
-
- Expires or null of no expiry
-
-
-
-
- The cookie creation date. This is automatically populated by the system on cookie creation.
-
-
-
-
- The cookie last access date. This is automatically populated by the system on access.
-
-
-
-
- Default implementation of it's used
- internally for the LoadHtml implementation - basically a resource handler is
- registered for a specific Url.
-
-
-
-
- Resource handler thread safe dictionary
-
-
-
-
- Create a new instance of DefaultResourceHandlerFactory
-
- string equality comparer
-
-
-
- Register a handler for the specified Url
-
- url
- The data in byte[] format that will be used for the response
- mime type
- Whether or not the handler should be used once (true) or until manually unregistered (false)
- returns true if the Url was successfully parsed into a Uri otherwise false
-
-
-
- Unregister a handler for the specified Url
-
- Url
- returns true if successfully removed
-
-
-
- Are there any 's registered?
-
-
-
-
- Called before a resource is loaded. To specify a handler for the resource return a object
-
- The browser UI control
- the browser object
- the frame object
- the request object - cannot be modified in this callback
- To allow the resource to load normally return NULL otherwise return an instance of ResourceHandler with a valid stream
-
-
-
- DependencyChecker provides a known list of Cef/CefSharp dependencies and
- provides helper methods to check for their existance.
-
-
-
-
- en-US Locales pak file location
-
-
-
-
- List of Cef Dependencies
-
-
-
-
- List of Cef Resources (pack files)
-
-
-
-
- List of CefSharp Dependencies
-
-
-
-
- List of CefSharp.BrowserSubprocess.exe dependencies.
-
-
-
-
- CheckDependencies iterates through the list of Cef and CefSharp dependencines
- relative to the path provided and returns a list of missing ones
-
- check to see if optional dependencies are present
- Is loading of pack files disabled?
- path to check for dependencies
- The path to the resources directory, if empty the Executing Assembly path is used.
- The path to a separate executable that will be launched for sub-processes.
- The locale pack file e.g.
- List of missing dependencies, if all present an empty List will be returned
-
-
-
- Loop through dependencies and add to the returned missing dependency list if not found.
-
- The directory of the dependencies, or the current directory if null.
- The dependencies to check.
- List of missing dependencies, if all present an empty List will be returned
-
-
-
- Checks if all Cef and CefSharp dependencies were found relative to the Executing Assembly.
- Shortcut method that calls , throws an Exception if not files are missing.
-
- The locale, if empty then en-US will be used.
- The path to the locales directory, if empty locales\ will be used.
- The path to the resources directory, if empty the Executing Assembly path is used.
- Is loading of pack files disabled?
- The path to a separate executable that will be launched for sub-processes.
- Throw when not all dependencies are present
-
-
-
- CefSharp interface for CefBrowser.
-
-
-
-
- Returns the browser host object. This method can only be called in the browser process.
-
- the browser host object
-
-
-
- Returns true if the browser can navigate backwards.
-
-
-
-
- Navigate backwards.
-
-
-
-
- Returns true if the browser can navigate forwards.
-
-
-
-
- Navigate forwards.
-
-
-
-
- Returns true if the browser is currently loading.
-
-
-
-
- Request that the browser close. The JavaScript 'onbeforeunload' event will
- be fired. If |forceClose| is false the event handler, if any, will be
- allowed to prompt the user and the user can optionally cancel the close.
- If |force_close| is true the prompt will not be displayed and the close
- will proceed. Results in a call to CefLifeSpanHandler::DoClose() if the
- event handler allows the close or if |force_close| is true. See
- CefLifeSpanHandler::DoClose() documentation for additional usage
- information.
-
-
-
-
- Reload the current page.
-
-
- true a reload is performed ignoring browser cache; false a reload is
- performed using files from the browser cache, if available.
-
-
-
-
- Stop loading the page.
-
-
-
-
- Returns the globally unique identifier for this browser.
-
-
-
-
- Returns true if this object is pointing to the same handle as that object.
-
- compare browser instances
- returns true if the same instance
-
-
-
- Returns true if the window is a popup window.
-
-
-
-
- Returns true if a document has been loaded in the browser.
-
-
-
-
- Returns the main (top-level) frame for the browser window.
-
-
-
-
- Returns the focused frame for the browser window.
-
-
-
-
- Returns the frame with the specified identifier, or NULL if not found.
-
- identifier
- frame or null
-
-
-
- Returns the frame with the specified name, or NULL if not found.
-
- name of frame
- frame or null
-
-
-
- Returns the number of frames that currently exist.
-
- the number of frames
-
-
-
- Returns the identifiers of all existing frames.
-
- list of frame identifiers
-
-
-
- Returns the names of all existing frames.
-
- frame names
-
-
-
- Gets a value indicating whether the browser has been disposed of.
-
-
-
-
- Interface used to represent the browser process aspects of a browser window.
- They may be called on any thread in that process unless otherwise indicated in the comments.
-
-
-
-
- Add the specified word to the spelling dictionary.
-
-
-
-
-
- Request that the browser close. The JavaScript 'onbeforeunload' event will be fired.
-
-
- If forceClose is false the event handler, if any, will be allowed to prompt the user and the
- user can optionally cancel the close. If forceClose is true the prompt will not be displayed
- and the close will proceed. Results in a call to if
- the event handler allows the close or if forceClose is true
- See documentation for additional usage information.
-
-
-
-
- Explicitly close the developer tools window if one exists for this browser instance.
-
-
-
-
- Returns true if this browser currently has an associated DevTools browser.
- Must be called on the CEF UI thread.
-
-
-
-
- Call this method when the user drags the mouse into the web view (before calling //).
-
-
-
-
- Call this method each time the mouse is moved across the web view during a drag operation (after calling and before calling /).
- This method is only used when window rendering is disabled.
-
-
-
-
- Call this method when the user completes the drag operation by dropping the object onto the web view (after calling ).
- The object being dropped is , given as an argument to the previous call.
- This method is only used when window rendering is disabled.
-
-
-
-
- Call this method when the drag operation started by a call has ended either in a drop or by being cancelled.
- If the web view is both the drag source and the drag target then all DragTarget* methods should be called before DragSource* methods.
- This method is only used when window rendering is disabled.
-
- x mouse coordinate relative to the upper-left corner of the view.
- y mouse coordinate relative to the upper-left corner of the view.
- Drag Operations mask
-
-
-
- Call this method when the user drags the mouse out of the web view (after calling ).
- This method is only used when window rendering is disabled.
-
-
-
-
- Call this method when the drag operation started by a call has completed.
- This method may be called immediately without first calling DragSourceEndedAt to cancel a drag operation.
- If the web view is both the drag source and the drag target then all DragTarget* methods should be called before DragSource* mthods.
- This method is only used when window rendering is disabled.
-
-
-
-
- Search for text
-
- can be used to have multiple searches running simultaniously
- text to search for
- indicates whether to search forward or backward within the page
- indicates whether the search should be case-sensitive
- indicates whether this is the first request or a follow-up
- The IFindHandler instance, if any, will be called to report find results.
-
-
-
- Returns the extension hosted in this browser or null if no extension is hosted. See for details.
-
-
-
-
- Retrieve the window handle of the browser that opened this browser.
-
- The handler
-
-
-
- Retrieve the window handle for this browser.
-
- The handler
-
-
-
- Get the current zoom level. The default zoom level is 0.0. This method can only be called on the CEF UI thread.
-
- a that when executed returns the zoom level as a double.
-
-
-
- Invalidate the view. The browser will call CefRenderHandler::OnPaint asynchronously.
- This method is only used when window rendering is disabled (OSR).
-
- indicates which surface to re-paint either View or Popup.
-
-
-
- Returns true if this browser is hosting an extension background script. Background hosts do not have a window and are not displayable.
- See for details.
-
- Returns true if this browser is hosting an extension background script.
-
-
-
- Begins a new composition or updates the existing composition. Blink has a
- special node (a composition node) that allows the input method to change
- text without affecting other DOM nodes.
-
- This method may be called multiple times as the composition changes. When
- the client is done making changes the composition should either be canceled
- or completed. To cancel the composition call ImeCancelComposition. To
- complete the composition call either ImeCommitText or
- ImeFinishComposingText. Completion is usually signaled when:
- The client receives a WM_IME_COMPOSITION message with a GCS_RESULTSTR
- flag (on Windows).
- This method is only used when window rendering is disabled. (WPF and OffScreen)
-
- is the optional text that
- will be inserted into the composition node
- is an optional set
- of ranges that will be underlined in the resulting text.
- is an optional range of the existing text that will be replaced. (MAC OSX ONLY)
- is an optional range of the resulting text that
- will be selected after insertion or replacement.
-
-
-
- Completes the existing composition by optionally inserting the specified
- text into the composition node.
- This method is only used when window rendering is disabled. (WPF and OffScreen)
-
- text that will be committed
- is an optional range of the existing text that will be replaced. (MAC OSX ONLY)
- is where the cursor will be positioned relative to the current cursor position. (MAC OSX ONLY)
-
-
-
- Completes the existing composition by applying the current composition node
- contents. See comments on ImeSetComposition for usage.
- This method is only used when window rendering is disabled. (WPF and OffScreen)
-
- If keepSelection is false the current selection, if any, will be discarded.
-
-
-
- Cancels the existing composition and discards the composition node
- contents without applying them. See comments on ImeSetComposition for
- usage.
- This method is only used when window rendering is disabled. (WPF and OffScreen)
-
-
-
-
- Get/Set Mouse cursor change disabled
-
-
-
-
- Notify the browser that the window hosting it is about to be moved or resized.
-
-
-
-
- Send a notification to the browser that the screen info has changed.
- The browser will then call CefRenderHandler::GetScreenInfo to update the screen information with the new values.
- This simulates moving the webview window from one display to another, or changing the properties of the current display.
- This method is only used when window rendering is disabled.
-
-
-
-
- Print the current browser contents.
-
-
-
-
- Asynchronously prints the current browser contents to the Pdf file specified.
- The caller is responsible for deleting the file when done.
-
- Output file location.
- Print Settings, can be null
- Callback executed when printing complete
-
-
-
- If a misspelled word is currently selected in an editable node calling this method will replace it with the specified word.
-
- word to be replaced
-
-
-
- Call to run a file chooser dialog. Only a single file chooser dialog may be pending at any given time.
- The dialog will be initiated asynchronously on the CEF UI thread.
-
- represents the type of dialog to display
- to the title to be used for the dialog and may be empty to show the default title ("Open" or "Save" depending on the mode)
- is the path with optional directory and/or file name component that will be initially selected in the dialog
- are used to restrict the selectable file types and may any combination of (a) valid lower-cased MIME types (e.g. "text/*" or "image/*"), (b) individual file extensions (e.g. ".txt" or ".png"), or (c) combined description and file extension delimited using "|" and ";" (e.g. "Image Types|.png;.gif;.jpg")
- is the 0-based index of the filter that will be selected by default
- will be executed after the dialog is dismissed or immediately if another dialog is already pending.
-
-
-
- Returns the request context for this browser.
-
-
-
-
- Issue a BeginFrame request to Chromium.
- Only valid when is set to true.
-
-
-
-
- Send a capture lost event to the browser.
-
-
-
-
- Send a focus event to the browser. . (Used for OSR Rendering e.g. WPF or OffScreen)
-
- set focus
-
-
-
- Send a key event to the browser.
-
- represents keyboard event
-
-
-
- Send key event to browser based on operating system message
-
- message
- wParam
- lParam
-
-
-
- Send a mouse click event to the browser.
-
- mouse event - x, y and modifiers
- Mouse ButtonType
- mouse up
- click count
-
-
-
- Send a mouse wheel event to the browser.
-
- mouse event - x, y and modifiers
- Movement delta for X direction.
- movement delta for Y direction.
-
-
-
- Set accessibility state for all frames. If accessibilityState is Default then accessibility will be disabled by default
- and the state may be further controlled with the "force-renderer-accessibility" and "disable-renderer-accessibility"
- command-line switches. If accessibilityState is STATE_ENABLED then accessibility will be enabled.
- If accessibilityState is STATE_DISABLED then accessibility will be completely disabled. For windowed browsers
- accessibility will be enabled in Complete mode (which corresponds to kAccessibilityModeComplete in Chromium).
- In this mode all platform accessibility objects will be created and managed by Chromium's internal implementation.
- The client needs only to detect the screen reader and call this method appropriately. For example, on Windows the
- client can handle WM_GETOBJECT with OBJID_CLIENT to detect accessibility readers. For windowless browsers accessibility
- will be enabled in TreeOnly mode (which corresponds to kAccessibilityModeWebContentsOnly in Chromium). In this mode
- renderer accessibility is enabled, the full tree is computed, and events are passed to IAccessibiltyHandler,
- but platform accessibility objects are not created. The client may implement platform accessibility objects using
- IAccessibiltyHandler callbacks if desired.
-
- may be default, enabled or disabled.
-
-
-
- Enable notifications of auto resize via IDisplayHandler.OnAutoResize. Notifications are disabled by default.
-
- enable auto resize
- minimum size
- maximum size
-
-
-
- Set whether the browser is focused. (Used for Normal Rendering e.g. WinForms)
-
- set focus
-
-
-
- Change the zoom level to the specified value. Specify 0.0 to reset the zoom level.
- If called on the CEF UI thread the change will be applied immediately.
- Otherwise, the change will be applied asynchronously on the UI thread.
-
- zoom level
-
-
-
- Open developer tools in its own window. If inspectElementAtX and/or inspectElementAtY are specified then
- the element at the specified (x,y) location will be inspected.
-
- window info used for showing dev tools
- x coordinate (used for inspectElement)
- y coordinate (used for inspectElement)
-
-
-
- Download the file at url using IDownloadHandler.
-
- url to download
-
-
-
- Cancel all searches that are currently going on.
-
- clear the selection
-
-
-
- Send a mouse move event to the browser, coordinates,
-
- mouse information, x and y values are relative to upper-left corner of view
- mouse leave
-
-
-
- Notify the browser that it has been hidden or shown.
- Layouting and rendering notification will stop when the browser is hidden.
- This method is only used when window rendering is disabled (WPF/OffScreen).
-
-
-
-
-
- Notify the browser that the widget has been resized.
- The browser will first call CefRenderHandler::GetViewRect to get the new size and then call CefRenderHandler::OnPaint asynchronously with the updated regions.
- This method is only used when window rendering is disabled.
-
-
-
-
- Retrieve a snapshot of current navigation entries as values sent to the
- specified visitor.
-
- visitor
- If true only the current navigation
- entry will be sent, otherwise all navigation entries will be sent.
-
-
-
- Returns the current visible navigation entry for this browser. This method
- can only be called on the CEF UI thread.
-
- the current navigation entry
-
-
-
- Gets/sets the maximum rate in frames per second (fps) that CefRenderHandler::
- OnPaint will be called for a windowless browser. The actual fps may be
- lower if the browser cannot generate frames at the requested rate. The
- minimum value is 1 and the maximum value is 60 (default 30). This method
- can only be called on the UI thread. Can also be set at browser creation
- via BrowserSettings.WindowlessFrameRate.
-
-
-
-
- Returns true if window rendering is disabled.
-
-
-
-
- Gets a value indicating whether the browserHost has been disposed of.
-
-
-
-
- This interface represents a CefFrame object (i.e. a HTML frame)
-
-
-
-
- True if this object is currently attached to a valid frame.
-
-
-
-
- Execute undo in this frame.
-
-
-
-
- Execute redo in this frame.
-
-
-
-
- Execute cut in this frame.
-
-
-
-
- Execute copy in this frame.
-
-
-
-
- Execute paste in this frame.
-
-
-
-
- Execute delete in this frame.
-
-
-
-
- Execute select all in this frame.
-
-
-
-
- Save this frame's HTML source to a temporary file and open it in the
- default text viewing application. This method can only be called from the
- browser process.
-
-
-
-
- Retrieve this frame's HTML source as a string sent to the specified visitor.
-
-
- a that when executed returns this frame's HTML source as a string.
-
-
-
-
- Retrieve this frame's HTML source as a string sent to the specified visitor.
- Use the method for a Task based async wrapper
-
- visitor will recieve string values asynchronously
-
-
-
- Retrieve this frame's display text as a string sent to the specified visitor.
-
-
- a that when executed returns the frame's display text as a string.
-
-
-
-
- Retrieve this frame's display text as a string sent to the specified visitor.
- Use the method for a Task based async wrapper
-
- visitor will recieve string values asynchronously
-
-
-
- Load the custom request. LoadRequest can only be used if a renderer process already exists.
- In newer versions initially loading about:blank no longer creates a renderer process. You
- can load a Data Uri initially then call this method.
- https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/Data_URIs
-
- request to be loaded in the frame
-
-
-
- Load the specified url.
-
- url to be loaded in the frame
-
-
-
- Load the contents of html with the specified dummy url.
-
- html to be loaded
- should have a standard scheme (for example, http scheme) or behaviors like
- link clicks and web security restrictions may not behave as expected.
-
-
-
- Execute a string of JavaScript code in this frame.
-
- Javascript to execute
- is the URL where the script in question can be found, if any.
- The renderer may request this URL to show the developer the source of the error.
- is the base line number to use for error reporting.
-
-
-
- Execute some Javascript code in the context of this WebBrowser, and return the result of the evaluation
- in an Async fashion
-
- The Javascript code that should be executed.
- is the URL where the script in question can be found, if any.
- is the base line number to use for error reporting.
- The timeout after which the Javascript code execution should be aborted.
- A Task that can be awaited to perform the script execution
-
-
-
- Returns true if this is the main (top-level) frame.
-
-
-
-
- Returns true if this is the focused frame.
-
-
-
-
- Returns the name for this frame. If the frame has an assigned name (for
- example, set via the iframe "name" attribute) then that value will be
- returned. Otherwise a unique name will be constructed based on the frame
- parent hierarchy. The main (top-level) frame will always have an empty name
- value.
-
-
-
-
- Returns the globally unique identifier for this frame or < 0 if the underlying frame does not yet exist.
-
-
-
-
- Returns the parent of this frame or NULL if this is the main (top-level) frame.
-
-
-
-
- Returns the URL currently loaded in this frame.
-
-
-
-
- Returns the browser that this frame belongs to.
-
-
-
-
- Gets a value indicating whether the frame has been disposed of.
-
-
-
-
- Create a custom request for use with
-
- Initialize the PostData object when creating this request
- A new instance of the request
-
-
-
- Class that creates instances for handling custom requests.
- The methods of this class will always be called on the CEF IO thread. This interface
- maps to the CefRequestHandler::GetResourceHandler method. It was split out to allow for
- the implementation that provides support
- for the LoadHtml extension method.
-
-
-
-
- Are there any 's registered?
-
-
-
-
- Called before a resource is loaded. To specify a handler for the resource return a object
-
- The browser UI control
- the browser object
- the frame object
- the request object - cannot be modified in this callback
- To allow the resource to load normally return NULL otherwise return an instance of ResourceHandler with a valid stream
-
-
-
- Class used to represent a web response. The methods of this class may be called on any thread.
-
-
-
-
- MimeType
-
-
-
-
- Response Headers
-
-
-
-
- Returns true if this object is read-only.
-
-
-
-
- Get/set the response error code.
-
-
-
-
- The status code of the response. Unless set, the default value used is 200
- (corresponding to HTTP status OK).
-
-
-
-
- Status Text
-
-
-
-
- Class representing window information.
-
-
-
-
- X coordinate
-
-
-
-
- Y coordinate
-
-
-
-
- Width
-
-
-
-
- Height
-
-
-
-
- Window style
-
-
-
-
- Ex window style
-
-
-
-
- Parent window handle
-
-
-
-
- Set to true to create the browser using windowless (off-screen) rendering.
- No window will be created for the browser and all rendering will occur via the
- IRenderHandler interface. The value will be used to identify monitor info
- and to act as the parent window for dialogs, context menus, etc. If | is not provided then the main screen monitor will be used and some functionality that requires a parent window may not function correctly.
- In order to create windowless browsers the CefSettings.WindowlessRenderingEnabled value must be set to true.
- Transparent painting is enabled by default but can be disabled by setting to an opaque value.
-
-
-
-
- Set to true to enable shared textures for windowless rendering. Only
- valid if is also set to true. Currently
- only supported on Windows (D3D11). This feature is experimental and has many bugs
- at the moment.
-
-
-
-
- Set to true to enable the ability to issue BeginFrame requests from the
- client application by calling .
-
-
-
-
- Handle for the new browser window. Only used with windowed rendering.
-
-
-
-
- Create the browser as a child window.
- Calls GetClientRect(Hwnd) to obtain the window bounds
-
- parent handle
-
-
-
- Create the browser as a child window.
-
- parent handle
- left
- top
- right
- bottom
-
-
-
- Create the browser as a popup window.
-
- parent handle
- window name
-
-
-
- Create the browser using windowless (off-screen) rendering.
- No window will be created for the browser and all rendering will occur via the CefRenderHandler interface. This window will automatically be transparent unless a colored backgrond is set in the browser settings.
-
- Value will be used to identify monitor info and to act as the parent window for dialogs, context menus, etc.
- If not provided then the main screen monitor will be used and some functionality that requires a parent window may not function correctly.
- In order to create windowless browsers the CefSettings.windowless_rendering_enabled value must be set to true.
-
-
-
- Struct representing a mouse event.
-
-
-
-
- x coordinate - relative to upper-left corner of view
-
-
-
-
- y coordinate - relative to upper-left corner of view
-
-
-
-
- Bit flags describing any pressed modifier keys.
-
-
-
-
- Mouse Event
-
- x coordinate relative to the upper-left corner of the view.
- y coordinate relative to the upper-left corner of the view.
- modifiers
-
-
-
- Used to represent drag data.
-
-
-
-
- Gets a copy of the current drag data
-
-
-
-
-
- Returns true if this object is read-only.
-
-
-
-
- Return the name of the file being dragged out of the browser window.
-
-
-
-
- Retrieve the list of file names that are being dragged into the browser window
-
-
-
-
- Return the base URL that the fragment came from. This value is used for resolving relative URLs and may be empty.
-
-
-
-
- Return the text/html fragment that is being dragged.
-
-
-
-
- Return the plain text fragment that is being dragged.
-
-
-
-
- Returns true if an image representation of drag data is available.
-
-
-
-
- Get the image representation of drag data.
- May return NULL if no image representation is available.
-
-
-
-
- Get the image hotspot (drag start location relative to image dimensions).
-
-
-
-
- Return the metadata, if any, associated with the link being dragged.
-
-
-
-
- Return the title associated with the link being dragged.
-
-
-
-
- Return the link URL that is being dragged.
-
-
-
-
- Returns true if the drag data is a file.
-
-
-
-
- Returns true if the drag data is a text or html fragment.
-
-
-
-
- Returns true if the drag data is a link
-
-
-
-
- Add a file that is being dragged into the webview.
-
- File Path
- Optional Display Name
-
-
-
- Reset the file contents. You should do this before calling
- CefBrowserHost::DragTargetDragEnter as the web view does not allow us to
- drag in this kind of data.
-
-
-
-
- Write the contents of the file being dragged out of the web view into the provided
- For a suggested filename check the property
-
- Stream data is to be written to. If null this method will return the
- size of the file contents in bytes.
- Returns the number of bytes written to the stream
-
-
-
- Gets a value indicating whether the object has been disposed of.
-
-
-
-
- Class used to represent a download item.
-
-
-
-
- Returns true if this object is valid. Do not call any other methods if this function returns false.
-
-
-
-
- Returns true if the download is in progress.
-
-
-
-
- Returns true if the download is complete.
-
-
-
-
- Returns true if the download has been canceled or interrupted.
-
-
-
-
- Returns a simple speed estimate in bytes/s.
-
-
-
-
- Returns the rough percent complete or -1 if the receive total size is unknown.
-
-
-
-
- Returns the total number of bytes.
-
-
-
-
- Returns the number of received bytes.
-
-
-
-
- Returns the time that the download started
-
-
-
-
- Returns the time that the download ended
-
-
-
-
- Returns the full path to the downloaded or downloading file.
-
-
-
-
- Returns the unique identifier for this download.
-
-
-
-
- Returns the URL.
-
-
-
-
- Returns the URL as it was before any redirects.
-
-
-
-
- Returns the suggested file name.
-
-
-
-
- Returns the content disposition.
-
-
-
-
- Returns the mime type.
-
-
-
-
- Wrapper for the CefContextMenuParams
-
-
-
-
- Returns the Y coordinate of the mouse where the context menu was invoked.
- Coords are relative to the associated RenderView's origin.
-
-
-
-
- Returns the X coordinate of the mouse where the context menu was invoked.
- Coords are relative to the associated RenderView's origin.
-
-
-
-
- Returns flags representing the type of node that the context menu was invoked on.
-
-
-
-
- Returns the URL of the link, if any, that encloses the node that the
- context menu was invoked on.
-
-
-
-
- Returns the link URL, if any, to be used ONLY for "copy link address". We
- don't validate this field in the frontend process.
-
-
-
-
- Returns the source URL, if any, for the element that the context menu was
- invoked on. Example of elements with source URLs are img, audio, and video.
-
-
-
-
- Returns true if the context menu was invoked on an image which has
- non-empty contents.
-
-
-
-
- Returns the URL of the top level page that the context menu was invoked on.
-
-
-
-
- Returns the URL of the subframe that the context menu was invoked on.
-
-
-
-
- Returns the character encoding of the subframe that the context menu was
- invoked on.
-
-
-
-
- Returns the type of context node that the context menu was invoked on.
-
-
-
-
- Returns flags representing the actions supported by the media element, if
- any, that the context menu was invoked on.
-
-
-
-
- Returns the text of the selection, if any, that the context menu was
- invoked on.
-
-
-
-
- Returns the text of the misspelled word, if any, that the context menu was
- invoked on.
-
-
-
-
- Returns a list of strings from the spell check service for the misspelled word if there is one.
-
-
-
-
- Returns true if the context menu was invoked on an editable node.
-
-
-
-
- Returns true if the context menu was invoked on an editable node where
- spell-check is enabled.
-
-
-
-
- Returns flags representing the actions supported by the editable node, if
- any, that the context menu was invoked on.
-
- Returns ContextMenuEditState as flags
-
-
-
- Returns true if the context menu contains items specified by the renderer
- process (for example, plugin placeholder or pepper plugin menu items).
-
-
-
-
- Returns true if the context menu was invoked from a pepper plugin.
-
-
-
-
- Gets a value indicating whether the object has been disposed of.
-
-
-
-
- JavascriptIgnoreAttribute - Methods and Properties marked with this attribute
- will be excluded from Javascript Binding
-
-
-
-
- Javascript Response
-
-
-
-
- Error message
-
-
-
-
- Was the javascript executed successfully
-
-
-
-
- Javascript response
-
-
-
-
- Post Data extension methods - Makes accessing post data easier
-
-
-
-
- A convenience extension method that extracts the Character set from
- the content-type header. Can be used in conjuncation with
-
- the request
- character set e.g. UTF-8
-
-
-
- Converts the property into a string
- using the specified charset (Encoding) or if unable to parse then uses
- the
-
- post data
- character set
- encoded string
-
-
-
- Add a new that represents the specified file
-
- post data instance
- file name
-
-
-
- Add a new that represents the key and value
- The data is encoded using
-
- Post Data
- Data to be encoded for the post data element
- Specified Encoding. If null then will be used
-
-
-
- Add a new that represents the key and value
-
- Post Data
- byte array that represents the post data
-
-
-
- IP Address solution callback result
-
-
-
-
- The result code - on success
-
-
-
-
- List of resolved IP addresses or empty if the resolution failed.
-
-
-
-
- ResolveCallbackResult
-
- result
- list of ip addresses
-
-
-
- Default implementation of . This latest implementation provides some simplification, at
- a minimum you only need to override ProcessRequestAsync. See the project source on GitHub for working examples.
- used to implement a custom request handler interface. The methods of this class will always be called on the IO thread.
- Static helper methods are included like FromStream and FromString that make dealing with fixed resources easy.
-
-
-
-
- MimeType to be used if none provided
-
-
-
-
- Gets or sets the Mime Type.
-
-
-
-
- Gets or sets the resource stream.
-
-
-
-
- Gets or sets the http status code.
-
-
-
-
- Gets or sets the status text.
-
-
-
-
- Gets or sets ResponseLength, when you know the size of your
- Stream (Response) set this property. This is optional.
- If you use a MemoryStream and don't provide a value
- here then it will be cast and it's size used
-
-
-
-
- Gets or sets the headers.
-
- The headers.
-
-
-
- When true the Stream will be Disposed when
- this instance is Disposed. The default value for
- this property is false.
-
-
-
-
- If the ErrorCode is set then the response will be ignored and
- the errorCode returned.
-
-
-
-
- Initializes a new instance of the class.
-
- Optional mimeType defaults to
- Optional Stream - must be set at some point to provide a valid response
- When true the Stream will be disposed when this instance is Diposed, you will
- be unable to use this ResourceHandler after the Stream has been disposed
-
-
-
- Begin processing the request. If you have the data in memory you can execute the callback
- immediately and return true. For Async processing you would typically spawn a Task to perform processing,
- then return true. When the processing is complete execute callback.Continue(); In your processing Task, simply set
- the StatusCode, StatusText, MimeType, ResponseLength and Stream
-
- The request object.
- The callback used to Continue or Cancel the request (async).
- To handle the request return true and call
- once the response header information is available
- can also be called from inside this method if
- header information is available immediately).
- To cancel the request return false.
-
-
-
- Populate the response stream, response length. When this method is called
- the response should be fully populated with data.
- It is possible to redirect to another url at this point in time.
- NOTE: It's no longer manditory to implement this method, you can simply populate the
- properties of this instance and they will be set by the default implementation.
-
- The response object used to set Headers, StatusCode, etc
- length of the response
- If set the request will be redirect to specified Url
- The response stream
-
-
-
- Called if the request is cancelled
-
-
-
-
- Gets the resource from the file path specified. Use the
- helper method to lookup the mimeType if required. Uses CefStreamResourceHandler for reading the data
-
- Location of the file.
- The mimeType if null then text/html is used.
- Dispose of the stream when finished with (you will only be able to serve one
- request).
- IResourceHandler.
-
-
-
- Creates a IResourceHandler that represents a Byte[], uses CefStreamResourceHandler for reading the data
-
- data
- mimeType
- IResourceHandler
-
-
-
- Gets the resource from the string.
-
- The text.
- The file extension.
- ResourceHandler.
-
-
-
- Gets a that represents a string.
- Without a Preamble, Cef will use BrowserSettings.DefaultEncoding to load the html.
-
- The html string
- Character Encoding
- Include encoding preamble
- Mime Type
- ResourceHandler
-
-
-
- Generates a ResourceHandler that has it's StatusCode set
-
- Body the response to be displayed
- StatusCode
- ResourceHandler
-
-
-
- Gets the resource from a stream.
-
- A stream of the resource.
- Type of MIME.
- Dispose of the stream when finished with (you will only be able to serve one
- request).
- ResourceHandler.
-
-
-
- Gets a MemoryStream from the given string using the provided encoding
-
- string to be converted to a stream
- encoding
- if true a BOM will be written to the beginning of the stream
- A memory stream from the given string
-
-
-
- Gets a byteArray from the given string using the provided encoding
-
- string to be converted to a stream
- encoding
- if true a BOM will be written to the beginning of the stream
- A memory stream from the given string
-
-
-
- Gets the MIME type of the content.
-
- The extension.
- System.String.
- extension
-
-
-
- Dispose of resources here
-
-
-
-
- FolderSchemeHandlerFactory is a very simple scheme handler that allows you
- to map requests for urls to a folder on your file system. For example
- creating a setting the rootFolder to c:\projects\CefSharp\CefSharp.Example\Resources
- registering the scheme handler
-
-
-
-
- Initialize a new instance of FolderSchemeHandlerFactory
-
- Root Folder where all your files exist, requests cannot be made outside of this folder
- if not null then schemeName checking will be implemented
- if not null then hostName checking will be implemented
- default page if no page specified, defaults to index.html
- file share mode used to open resources, defaults to FileShare.Read
-
-
-
- If the file requested is within the rootFolder then a IResourceHandler reference to the file requested will be returned
- otherwise a 404 ResourceHandler will be returned.
-
- the browser window that originated the
- request or null if the request did not originate from a browser window
- (for example, if the request came from CefURLRequest).
- frame that originated the request
- or null if the request did not originate from a browser window
- (for example, if the request came from CefURLRequest).
- the scheme name
- The request. (will not contain cookie data)
-
- A IResourceHandler
-
-
-
-
- Class that creates instances for handling scheme requests.
- The methods of this class will always be called on the CEF IO thread.
-
-
-
-
- Return a new instance to handle the request or an empty
- reference to allow default handling of the request.
-
- the browser window that originated the
- request or null if the request did not originate from a browser window
- (for example, if the request came from CefURLRequest).
- frame that originated the request
- or null if the request did not originate from a browser window
- (for example, if the request came from CefURLRequest).
- the scheme name
- The request. (will not contain cookie data)
-
- Return a new instance to handle the request or an empty
- reference to allow default handling of the request
-
-
-
-
- Class representing the SSL information for a navigation entry.
-
-
-
-
- Returns true if the status is related to a secure SSL/TLS connection.
-
-
-
-
- Returns a bitmask containing any and all problems verifying the server
- certificate.
-
-
-
-
-
- Returns the SSL version used for the SSL connection.
-
-
-
-
-
- Returns a bitmask containing the page security content status.
-
-
-
-
- Returns the X.509 certificate.
-
-
-
-
- SslStatus
-
- is secure
- cert status
- ssl version
- content status
- certificate
-
-
-
- Used in conjunction with CefSettings.RegisterScheme to register a scheme.
- You can register your own custom scheme e.g. custom:// or use an existing
- scheme e.g. http://
-
-
-
-
- Schema Name e.g. custom
-
-
-
-
- Optional Domain Name. An empty value for a standard scheme
- will cause the factory to match all domain names. The |domain_name| value
- will be ignored for non-standard schemes.
-
-
-
-
- If true the scheme will be treated as a standard scheme.
- Standard schemes are subject to URL canonicalization and parsing rules as
- defined in the Common Internet Scheme Syntax RFC 1738 Section 3.1 available
- at http://www.ietf.org/rfc/rfc1738.txt
-
- In particular, the syntax for standard scheme URLs must be of the form:
-
- Standard scheme URLs must have a host component that is a fully qualified
- domain name as defined in Section 3.5 of RFC 1034 [13] and Section 2.1 of
- RFC 1123. These URLs will be canonicalized to "scheme://host/path" in the
- simplest case and "scheme://username:password@host:port/path" in the most
- explicit case. For example, "scheme:host/path" and "scheme:///host/path"
- will both be canonicalized to "scheme://host/path". The origin of a
- standard scheme URL is the combination of scheme, host and port (i.e.,
- "scheme://host:port" in the most explicit case).
-
- For non-standard scheme URLs only the "scheme:" component is parsed and
- canonicalized. The remainder of the URL will be passed to the handler
- as-is. For example, "scheme:///some%20text" will remain the same.
- Non-standard scheme URLs cannot be used as a target for form submission.
-
-
-
-
- If true the scheme will be treated as local (i.e. with the
- same security rules as those applied to "file" URLs). Normal pages cannot
- link to or access local URLs. Also, by default, local URLs can only perform
- XMLHttpRequest calls to the same URL (origin + path) that originated the
- request. To allow XMLHttpRequest calls from a local URL to other URLs with
- the same origin set the CefSettings.file_access_from_file_urls_allowed
- value to true. To allow XMLHttpRequest calls from a local URL to all
- origins set the CefSettings.universal_access_from_file_urls_allowed value
- to true.
-
-
-
-
- If true the scheme will be treated as display-isolated.
- This means that pages cannot display these URLs unless they are
- from the same scheme. For example, pages in another origin cannot create
- iframes or hyperlinks to URLs with this scheme.
-
-
-
-
- If true the scheme will be treated with the same security
- rules as those applied to "https" URLs. For example, loading this scheme
- from other secure schemes will not trigger mixed content warnings.
-
-
-
-
- If true the scheme can be sent CORS requests.
- This value should be true in most cases where IsStandard is true.
-
-
-
-
- If true the scheme can bypass Content-Security-Policy(CSP) checks.
- This value should be false in most cases where IsStandard is true.
-
-
-
-
- Factory Class that creates instances
- for handling scheme requests. Leave this null if you wish to manually register the
- scheme handler with the relevant RequestContext.
-
-
-
-
- Creates a new CefCustomScheme.
-
-
-
-
- Method used internally
-
- command line arguments
- list of scheme objects
-
-
-
- Interface to implement for visiting cookie values.
- The methods of this class will always be called on the IO thread.
- If there are no cookies then Visit will never be called, you must implement
- Dispose to handle this scenario.
-
-
-
-
- Method that will be called once for each cookie. This method may never be called if no cookies are found.
-
- cookie
- is the 0-based index for the current cookie.
- is the total number of cookies.
- Set to true to delete the cookie currently being visited.
- Return false to stop visiting cookies otherwise true
-
-
-
- Callback interface for IBrowserHost.GetNavigationEntries.
- The methods of this class will be called on the CEF UI thread.
-
-
-
-
- Method that will be executed.
-
- if the navigationEntry will be invalid then
- is true if this entry is the currently loaded navigation entry
- is the 0-based index of this entry
- is the total number of entries.
- Return true to continue visiting entries or false to stop.
-
-
-
- Implement this interface to receive string values asynchronously.
-
-
-
-
- Method that will be executed.
-
- string (result of async execution)
-
-
-
- Interface to implement for visiting web plugin information.
- The methods of this class will be called on the CEF UI thread,
- which by default is not the same as your application UI
-
-
-
-
- Method that will be called once for each plugin.
- This method may never be called if no plugins are found.
-
- plugin information
- is the 0-based index for the current plugin
- total is the total number of plugins.
- Return false to stop visiting plugins otherwise true
-
-
-
- Cookie Visitor implementation that uses a TaskCompletionSource
- to return a List of cookies
-
-
-
-
- Default constructor
-
-
-
-
- Task that can be awaited for the result to be retrieved async
-
-
-
-
- A that uses a TaskCompletionSource
- to simplify things
-
-
-
-
- Default constructor
-
-
-
-
- Task that can be awaited for the result to be retrieved async
-
-
-
-
- Provides a visitor implementation of
-
-
-
-
- Default constructor
-
-
-
-
- Task that can be awaited for the result to be retrieved async
-
-
-
-
- A that uses a TaskCompletionSource
- to simplify things
-
-
-
-
- Default constructor
-
-
-
-
- Method that will be executed.
-
- string (result of async execution)
-
-
-
- Task that can be awaited for the result to be retrieved async
-
-
-
-
- WebBrowser extensions - These methods make performing common tasks
- easier.
-
-
-
-
- Returns the main (top-level) frame for the browser window.
-
- Frame
-
-
-
- Returns the focused frame for the browser window.
-
- Frame
-
-
-
- Execute Undo on the focused frame
-
- The ChromiumWebBrowser instance this method extends
-
-
-
- Execute Redo on the focused frame
-
- The ChromiumWebBrowser instance this method extends
-
-
-
- Execute Cut on the focused frame
-
- The ChromiumWebBrowser instance this method extends
-
-
-
- Execute Copy on the focused frame
-
- The ChromiumWebBrowser instance this method extends
-
-
-
- Execute Paste on the focused frame
-
- The ChromiumWebBrowser instance this method extends
-
-
-
- Execute Delete on the focused frame
-
- The ChromiumWebBrowser instance this method extends
-
-
-
- Execute SelectAll on the focused frame
-
- The ChromiumWebBrowser instance this method extends
-
-
-
- Opens up a new program window (using the default text editor) where the source code of the currently displayed web
- page is shown.
-
- The ChromiumWebBrowser instance this method extends
-
-
-
- Retrieve the main frame's HTML source using a .
-
- The ChromiumWebBrowser instance this method extends
- that when executed returns the frame source as a string
-
-
-
- Retrieve the main frame's display text using a .
-
- The ChromiumWebBrowser instance this method extends
- that when executed returns the frame display text as a string.
-
-
-
- Execute some Javascript code in the context of this WebBrowser. As the method name implies, the script will be
- executed asynchronously, and the method therefore returns before the script has actually been executed.
- This simple helper extension will encapsulate params in single quotes (unless int, uint, etc)
-
- The ChromiumWebBrowser instance this method extends
- The javascript method name to execute
- the arguments to be passed as params to the method. Args are encoded using ,
- you can provide a custom implementation if you require a custom implementation
-
-
-
- Execute some Javascript code in the context of this WebBrowser. As the method name implies, the script will be
- executed asynchronously, and the method therefore returns before the script has actually been executed.
-
- The ChromiumWebBrowser instance this method extends
- The Javascript code that should be executed.
-
-
-
- Execute Javascript code in the context of this WebBrowser. This extension method uses the LoadingStateChanged event.
- As the method name implies, the script will be executed asynchronously, and the method therefore returns before the
- script has actually been executed.
-
- The ChromiumWebBrowser instance this method extends
- The Javascript code that should be executed.
- The script will only be executed on first page load, subsiquent page loads will be ignored
- Best effort is made to make sure the script is executed, there are likely a few edge cases where the script
- won't be executed, if you suspect your script isn't being executed, then try executing in the LoadingStateChanged
- event handler to confirm that it does indeed get executed.
-
-
-
- Creates a new instance of IRequest with the specified Url and Method = POST
- and then calls .
- can only be used if a renderer process already exists.
- In newer versions initially loading about:blank no longer creates a renderer process. You
- can load a Data Uri initially then call this method.
- https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/Data_URIs
-
-
-
-
-
- This is an extension method
-
-
-
- Load the string contents with the specified dummy url. Web security restrictions may not behave as expected.
-
- The ChromiumWebBrowser instance this method extends
- html string to load
- the url should have a standard scheme (for example, http scheme) or behaviors like link clicks
-
-
-
- Registers and loads a that represents the HTML content.
-
-
- `Cef` Native `LoadHtml` is unpredictable and only works sometimes, this method wraps
- the provided HTML in a and loads the provided url using
- the method.
- Defaults to using for character encoding
- The url must start with a valid schema, other uri's such as about:blank are invalid
- A valid example looks like http://test/page
-
- The ChromiumWebBrowser instance this method extends
- The HTML content.
- The URL that will be treated as the address of the content.
- returns false if the Url was not successfully parsed into a Uri
-
-
-
- Loads html as Data Uri
- See https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/Data_URIs for details
- If base64Encode is false then html will be Uri encoded
-
- The ChromiumWebBrowser instance this method extends
- Html to load as data uri.
- if true the html string will be base64 encoded using UTF8 encoding.
-
-
-
- Registers and loads a that represents the HTML content.
-
-
- `Cef` Native `LoadHtml` is unpredictable and only works sometimes, this method wraps
- the provided HTML in a and loads the provided url using
- the method.
-
- The ChromiumWebBrowser instance this method extends
- The HTML content.
- The URL that will be treated as the address of the content.
- Character Encoding
- Whether or not the handler should be used once (true) or until manually unregistered (false)
- returns false if the Url was not successfully parsed into a Uri
-
-
-
- Register a ResourceHandler. Can only be used when browser.ResourceHandlerFactory is an instance of DefaultResourceHandlerFactory
-
- The ChromiumWebBrowser instance this method extends
- the url of the resource to unregister
- Stream to be registered, the stream should not be shared with any other instances of DefaultResourceHandlerFactory
- the mimeType
- Whether or not the handler should be used once (true) or until manually unregistered (false). If true the Stream
- will be Diposed of when finished.
-
-
-
- Unregister a ResourceHandler. Can only be used when browser.ResourceHandlerFactory is an instance of DefaultResourceHandlerFactory
-
- The ChromiumWebBrowser instance this method extends
- the url of the resource to unregister
-
-
-
- Stops loading the current page.
-
-
-
-
- Navigates back, must check before calling this method.
-
-
-
-
- Navigates forward, must check before calling this method.
-
-
-
-
- Reloads the page being displayed. This method will use data from the browser's cache, if available.
-
-
-
-
- Reloads the page being displayed, optionally ignoring the cache (which means the whole page including all .css, .js
- etc. resources will be re-fetched).
-
- The ChromiumWebBrowser instance this method extends
- true A reload is performed ignoring browser cache; false A reload is
- performed using files from the browser cache, if available.
-
-
-
- Gets the default cookie manager associated with the IWebBrowser
-
- The ChromiumWebBrowser instance this method extends
- If not null it will be executed asnychronously on the
- CEF IO thread after the manager's storage has been initialized.
- Cookie Manager
-
-
-
- Asynchronously gets the current Zoom Level.
-
-
-
-
- Asynchronously gets the current Zoom Level.
-
-
-
-
- Change the ZoomLevel to the specified value. Can be set to 0.0 to clear the zoom level.
-
-
- If called on the CEF UI thread the change will be applied immediately.
- Otherwise, the change will be applied asynchronously on the CEF UI thread.
- The CEF UI thread is different to the WPF/WinForms UI Thread
-
- The ChromiumWebBrowser instance this method extends
- zoom level
-
-
-
- Change the ZoomLevel to the specified value. Can be set to 0.0 to clear the zoom level.
-
-
- If called on the CEF UI thread the change will be applied immediately.
- Otherwise, the change will be applied asynchronously on the CEF UI thread.
- The CEF UI thread is different to the WPF/WinForms UI Thread
-
- The ChromiumWebBrowser instance this method extends
- zoom level
-
-
-
- Search for text within the current page.
-
- The ChromiumWebBrowser instance this method extends
- Can be used in can conjunction with searchText to have multiple
- searches running simultaneously.
- search text
- indicates whether to search forward or backward within the page.
- indicates whether the search should be case-sensitive.
- indicates whether this is the first request or a follow-up.
-
-
-
- Search for text within the current page.
-
- The ChromiumWebBrowser instance this method extends
- Can be used in can conjunction with searchText to have multiple
- searches running simultaneously.
- search text
- indicates whether to search forward or backward within the page.
- indicates whether the search should be case-sensitive.
- indicates whether this is the first request or a follow-up.
-
-
-
- Cancel all searches that are currently going on.
-
- The ChromiumWebBrowser instance this method extends
- clear the current search selection
-
-
-
- Cancel all searches that are currently going on.
-
- The ChromiumWebBrowser instance this method extends
- clear the current search selection
-
-
-
- Opens a Print Dialog which if used (can be user cancelled) will print the browser contents.
-
- The ChromiumWebBrowser instance this method extends
-
-
-
- Asynchronously prints the current browser contents to the PDF file specified.
- The caller is responsible for deleting the file when done.
-
- The object this method extends.
- Output file location.
- Print Settings.
- A task that represents the asynchronous print operation.
- The result is true on success or false on failure to generate the Pdf.
-
-
-
- Opens a Print Dialog which if used (can be user cancelled) will print the browser contents.
-
- The ChromiumWebBrowser instance this method extends
-
-
-
- Asynchronously prints the current browser contents to the PDF file specified.
- The caller is responsible for deleting the file when done.
-
- The ChromiumWebBrowser instance this method extends
- Output file location.
- Print Settings.
- A task that represents the asynchronous print operation.
- The result is true on success or false on failure to generate the Pdf.
-
-
-
- Open developer tools in its own window.
-
- The ChromiumWebBrowser instance this method extends
-
-
-
- Open developer tools in its own window.
-
- The ChromiumWebBrowser instance this method extends
-
-
-
- Explicitly close the developer tools window if one exists for this browser instance.
-
- The ChromiumWebBrowser instance this method extends
-
-
-
- Explicitly close the developer tools window if one exists for this browser instance.
-
- The ChromiumWebBrowser instance this method extends
-
-
-
- If a misspelled word is currently selected in an editable node calling
- this method will replace it with the specified word.
-
- The ChromiumWebBrowser instance this method extends
- The new word that will replace the currently selected word.
-
-
-
- If a misspelled word is currently selected in an editable node calling
- this method will replace it with the specified word.
-
- The ChromiumWebBrowser instance this method extends
- The new word that will replace the currently selected word.
-
-
-
- Add the specified word to the spelling dictionary.
-
- The ChromiumWebBrowser instance this method extends
- The new word that will be added to the dictionary.
-
-
-
- Shortcut method to get the browser IBrowserHost
-
- The ChromiumWebBrowser instance this method extends
- browserHost or null
-
-
-
- Add the specified word to the spelling dictionary.
-
- The ChromiumWebBrowser instance this method extends
- The new word that will be added to the dictionary.
-
-
-
- Evaluate some Javascript code in the context of this WebBrowser. The script will be executed asynchronously and the
- method returns a Task encapsulating the response from the Javascript
- This simple helper extension will encapsulate params in single quotes (unless int, uint, etc)
-
- The ChromiumWebBrowser instance this method extends
- The javascript method name to execute
- the arguments to be passed as params to the method
- that can be awaited to perform the script execution
-
-
-
- Evaluate some Javascript code in the context of this WebBrowser using the specified timeout. The script will be executed asynchronously and the
- method returns a Task encapsulating the response from the Javascript
- This simple helper extension will encapsulate params in single quotes (unless int, uint, etc).
-
- The ChromiumWebBrowser instance this method extends
- The timeout after which the Javascript code execution should be aborted.
- The javascript method name to execute
- the arguments to be passed as params to the method. Args are encoded using ,
- you can provide a custom implementation if you require a custom implementation
- that can be awaited to perform the script execution
-
-
-
- Function used to encode the params passed to ,
- and
- Provide your own custom function to perform custom encoding. You can use your choice
- of JSON encoder here if you should so choose.
-
-
-
-
- Checks if the given object is a numerical object
-
- The object to check
- True if numeric, otherwise false
-
-
-
- Transforms the methodName and arguments into valid Javascript code. Will encapsulate params in single quotes (unless int, uint, etc)
-
- The javascript method name to execute
- the arguments to be passed as params to the method
- The Javascript code
-
-
-
- Information about a specific web plugin.
-
-
-
-
- Gets or sets the plugin name (i.e. Flash).
-
-
-
-
- Gets or sets tge description of the plugin from the version information.
-
-
-
-
- Gets or sets the plugin file path (DLL/bundle/library).
-
-
-
-
- Gets or sets the version of the plugin (may be OS-specific).
-
-
-
-
- WebPluginInfo
-
- name
- description
- path
- version
-
-
-
- Class used to represent a web request. The methods of this class may be called on any thread.
-
-
-
-
- Get/Set request flags, can be used to control caching policy
-
-
-
-
- Request Url
-
-
-
-
- Returns the globally unique identifier for this request or 0 if not specified.
- Can be used by implementations in the browser process to track a
- single request across multiple callbacks.
-
-
-
-
- Request Method GET/POST etc
-
-
-
-
- Set the referrer URL and policy. If non-empty the referrer URL must be
- fully qualified with an HTTP or HTTPS scheme component. Any username,
- password or ref component will be removed.
-
- the referrer url
- referrer policy
-
-
-
- Get the referrer URL.
-
-
-
-
- Get the resource type for this request.
-
-
-
-
- Get the referrer policy.
-
-
-
-
- Header Collection
- NOTE: This collection is a copy of the underlying type, to make changes, take a reference to the collection,
- make your changes, then reassign the collection. At some point this will be replaced with a proper wrapper.
-
-
-
-
- Post data
-
-
-
-
- Get the transition type for this request.
- Applies to requests that represent a main frame or sub-frame navigation.
-
-
-
-
- Gets a value indicating whether the request has been disposed of.
-
-
-
-
- Returns true if this object is read-only.
-
-
-
-
- Initialize a new instance of .
- Make sure to check if the is null
- before calling otherwise the existing data will be overridden.
-
-
-
-
- ChromiumWebBrowser implementations implement this interface. Can be cast to
- the concrete implementation to access UI specific features.
-
-
-
-
-
- Event handler for receiving Javascript console messages being sent from web pages.
- It's important to note this event is fired on a CEF UI thread, which by default is not the same as your application UI
- thread. It is unwise to block on this thread for any length of time as your browser will become unresponsive and/or hang..
- To access UI elements you'll need to Invoke/Dispatch onto the UI Thread.
- (The exception to this is when your running with settings.MultiThreadedMessageLoop = false, then they'll be the same thread).
-
-
-
-
- Event handler for changes to the status message.
- It's important to note this event is fired on a CEF UI thread, which by default is not the same as your application UI
- thread. It is unwise to block on this thread for any length of time as your browser will become unresponsive and/or hang.
- To access UI elements you'll need to Invoke/Dispatch onto the UI Thread.
- (The exception to this is when your running with settings.MultiThreadedMessageLoop = false, then they'll be the same thread).
-
-
-
-
- Event handler that will get called when the browser begins loading a frame. Multiple frames may be loading at the same
- time. Sub-frames may start or continue loading after the main frame load has ended. This method may not be called for a
- particular frame if the load request for that frame fails. For notification of overall browser load status use
- OnLoadingStateChange instead.
- It's important to note this event is fired on a CEF UI thread, which by default is not the same as your application UI
- thread. It is unwise to block on this thread for any length of time as your browser will become unresponsive and/or hang..
- To access UI elements you'll need to Invoke/Dispatch onto the UI Thread.
-
- Whilst this may seem like a logical place to execute js, it's called before the DOM has been loaded, implement
- as it's called when the underlying V8Context is created
-
-
-
-
- Event handler that will get called when the browser is done loading a frame. Multiple frames may be loading at the same
- time. Sub-frames may start or continue loading after the main frame load has ended. This method will always be called
- for all frames irrespective of whether the request completes successfully.
- It's important to note this event is fired on a CEF UI thread, which by default is not the same as your application UI
- thread. It is unwise to block on this thread for any length of time as your browser will become unresponsive and/or hang..
- To access UI elements you'll need to Invoke/Dispatch onto the UI Thread.
-
-
-
-
- Event handler that will get called when the resource load for a navigation fails or is canceled.
- It's important to note this event is fired on a CEF UI thread, which by default is not the same as your application UI
- thread. It is unwise to block on this thread for any length of time as your browser will become unresponsive and/or hang..
- To access UI elements you'll need to Invoke/Dispatch onto the UI Thread.
-
-
-
-
- Event handler that will get called when the Loading state has changed.
- This event will be fired twice. Once when loading is initiated either programmatically or
- by user action, and once when loading is terminated due to completion, cancellation of failure.
- It's important to note this event is fired on a CEF UI thread, which by default is not the same as your application UI
- thread. It is unwise to block on this thread for any length of time as your browser will become unresponsive and/or hang..
- To access UI elements you'll need to Invoke/Dispatch onto the UI Thread.
-
-
-
-
- Loads the specified URL.
-
- The URL to be loaded.
-
-
-
- Registers a Javascript object in this specific browser instance.
-
- The name of the object. (e.g. "foo", if you want the object to be accessible as window.foo).
- The object to be made accessible to Javascript.
- binding options - camelCaseJavascriptNames default to true
-
-
-
- Asynchronously registers a Javascript object in this specific browser instance.
- Only methods of the object will be available.
-
- The name of the object. (e.g. "foo", if you want the object to be accessible as window.foo).
- The object to be made accessible to Javascript.
- binding options - camelCaseJavascriptNames default to true
- The registered methods can only be called in an async way, they will all return immeditaly and the resulting
- object will be a standard javascript Promise object which is usable to wait for completion or failure.
-
-
-
- The javascript object repository, one repository per ChromiumWebBrowser instance.
-
-
-
-
- Implement and assign to handle dialog events.
-
- The dialog handler.
-
-
-
- Implement and assign to handle events related to browser requests.
-
- The request handler.
-
-
-
- Implement and assign to handle events related to browser display state.
-
- The display handler.
-
-
-
- Implement and assign to handle events related to browser load status.
-
- The load handler.
-
-
-
- Implement and assign to handle events related to popups.
-
- The life span handler.
-
-
-
- Implement and assign to handle events related to key press.
-
- The keyboard handler.
-
-
-
- Implement and assign to handle events related to JavaScript Dialogs.
-
- The js dialog handler.
-
-
-
- Implement and assign to handle events related to dragging.
-
- The drag handler.
-
-
-
- Implement and assign to handle events related to downloading files.
-
- The download handler.
-
-
-
- Implement and assign to handle events related to the browser context menu
-
- The menu handler.
-
-
-
- Implement and assign to handle events related to the browser component's focus
-
- The focus handler.
-
-
-
- Implement and control the loading of resources
-
- The resource handler factory.
-
-
-
- Implement and assign to handle messages from the render process.
-
- The render process message handler.
-
-
-
- Implement to handle events related to find results.
-
- The find handler.
-
-
-
- A flag that indicates whether the WebBrowser is initialized (true) or not (false).
-
- true if this instance is browser initialized; otherwise, false.
- In the WPF control, this property is implemented as a Dependency Property and fully supports data
- binding.
-
-
-
- A flag that indicates whether the control is currently loading one or more web pages (true) or not (false).
-
- true if this instance is loading; otherwise, false.
- In the WPF control, this property is implemented as a Dependency Property and fully supports data
- binding.
-
-
-
- A flag that indicates whether the state of the control current supports the GoBack action (true) or not (false).
-
- true if this instance can go back; otherwise, false.
- In the WPF control, this property is implemented as a Dependency Property and fully supports data
- binding.
-
-
-
- A flag that indicates whether the state of the control currently supports the GoForward action (true) or not (false).
-
- true if this instance can go forward; otherwise, false.
- In the WPF control, this property is implemented as a Dependency Property and fully supports data
- binding.
-
-
-
- The address (URL) which the browser control is currently displaying.
- Will automatically be updated as the user navigates to another page (e.g. by clicking on a link).
-
- The address.
- In the WPF control, this property is implemented as a Dependency Property and fully supports data
- binding.
-
-
-
- The text that will be displayed as a ToolTip
-
- The tooltip text.
-
-
-
- A flag that indicates if you can execute javascript in the main frame.
- Flag is set to true in IRenderProcessMessageHandler.OnContextCreated.
- and false in IRenderProcessMessageHandler.OnContextReleased
-
-
-
-
- Gets the custom request context assigned to this browser instance
- If no instance was assigned this will be null and the global
- request context will have been used for this browser.
- You can access the global request context through Cef.GetGlobalRequestContext()
-
-
-
-
- Attempts to give focus to the IWebBrowser control.
-
- true if keyboard focus and logical focus were set to this element; false if only logical focus
- was set to this element, or if the call to this method did not force the focus to change.
-
-
-
- Returns the current CEF Browser Instance
-
- browser instance or null
-
-
-
diff --git a/src/bin/CefSharp.dll b/src/bin/CefSharp.dll
deleted file mode 100644
index cd3490a..0000000
Binary files a/src/bin/CefSharp.dll and /dev/null differ
diff --git a/src/bin/README.txt b/src/bin/README.txt
deleted file mode 100644
index 7071cce..0000000
--- a/src/bin/README.txt
+++ /dev/null
@@ -1,156 +0,0 @@
-Chromium Embedded Framework (CEF) Standard Binary Distribution for Windows
--------------------------------------------------------------------------------
-
-Date: January 12, 2019
-
-CEF Version: 3.3578.1863.gbf8cff2
-CEF URL: https://bitbucket.org/chromiumembedded/cef.git
- @bf8cff263c07bd74cf57050d755fb48a8cde00fc
-
-Chromium Version: 71.0.3578.98
-Chromium URL: https://chromium.googlesource.com/chromium/src.git
- @c2bec8045f7ad3ece1c5d80236183a21c1fac3f5
-
-This distribution contains all components necessary to build and distribute an
-application using CEF on the Windows platform. Please see the LICENSING
-section of this document for licensing terms and conditions.
-
-
-CONTENTS
---------
-
-cmake Contains CMake configuration files shared by all targets.
-
-Debug Contains libcef.dll, libcef.lib and other components required to
- build and run the debug version of CEF-based applications. By
- default these files should be placed in the same directory as the
- executable and will be copied there as part of the build process.
-
-include Contains all required CEF header files.
-
-libcef_dll Contains the source code for the libcef_dll_wrapper static library
- that all applications using the CEF C++ API must link against.
-
-Release Contains libcef.dll, libcef.lib and other components required to
- build and run the release version of CEF-based applications. By
- default these files should be placed in the same directory as the
- executable and will be copied there as part of the build process.
-
-Resources Contains resources required by libcef.dll. By default these files
- should be placed in the same directory as libcef.dll and will be
- copied there as part of the build process.
-
-tests/ Directory of tests that demonstrate CEF usage.
-
- cefclient Contains the cefclient sample application configured to build
- using the files in this distribution. This application demonstrates
- a wide range of CEF functionalities.
-
- cefsimple Contains the cefsimple sample application configured to build
- using the files in this distribution. This application demonstrates
- the minimal functionality required to create a browser window.
-
- ceftests Contains unit tests that exercise the CEF APIs.
-
- gtest Contains the Google C++ Testing Framework used by the ceftests
- target.
-
- shared Contains source code shared by the cefclient and ceftests targets.
-
-
-USAGE
------
-
-Building using CMake:
- CMake can be used to generate project files in many different formats. See
- usage instructions at the top of the CMakeLists.txt file.
-
-Please visit the CEF Website for additional usage information.
-
-https://bitbucket.org/chromiumembedded/cef/
-
-
-REDISTRIBUTION
---------------
-
-This binary distribution contains the below components.
-
-Required components:
-
-The following components are required. CEF will not function without them.
-
-* CEF core library.
- * libcef.dll
-
-* Crash reporting library.
- * chrome_elf.dll
-
-* Unicode support data.
- * icudtl.dat
-
-* V8 snapshot data.
- * natives_blob.bin
- * snapshot_blob.bin
- * v8_context_snapshot.bin
-
-Optional components:
-
-The following components are optional. If they are missing CEF will continue to
-run but any related functionality may become broken or disabled.
-
-* Localized resources.
- Locale file loading can be disabled completely using
- CefSettings.pack_loading_disabled. The locales directory path can be
- customized using CefSettings.locales_dir_path.
-
- * locales/
- Directory containing localized resources used by CEF, Chromium and Blink. A
- .pak file is loaded from this directory based on the CefSettings.locale
- value. Only configured locales need to be distributed. If no locale is
- configured the default locale of "en-US" will be used. Without these files
- arbitrary Web components may display incorrectly.
-
-* Other resources.
- Pack file loading can be disabled completely using
- CefSettings.pack_loading_disabled. The resources directory path can be
- customized using CefSettings.resources_dir_path.
-
- * cef.pak
- * cef_100_percent.pak
- * cef_200_percent.pak
- These files contain non-localized resources used by CEF, Chromium and Blink.
- Without these files arbitrary Web components may display incorrectly.
-
- * cef_extensions.pak
- This file contains non-localized resources required for extension loading.
- Pass the `--disable-extensions` command-line flag to disable use of this
- file. Without this file components that depend on the extension system,
- such as the PDF viewer, will not function.
-
- * devtools_resources.pak
- This file contains non-localized resources required for Chrome Developer
- Tools. Without this file Chrome Developer Tools will not function.
-
-* Angle and Direct3D support.
- * d3dcompiler_43.dll (required for Windows XP)
- * d3dcompiler_47.dll (required for Windows Vista and newer)
- * libEGL.dll
- * libGLESv2.dll
- Without these files HTML5 accelerated content like 2D canvas, 3D CSS and WebGL
- will not function.
-
-* SwiftShader support.
- * swiftshader/libEGL.dll
- * swiftshader/libGLESv2.dll
- Without these files WebGL will not function in software-only mode when the GPU
- is not available or disabled.
-
-
-LICENSING
----------
-
-The CEF project is BSD licensed. Please read the LICENSE.txt file included with
-this binary distribution for licensing terms and conditions. Other software
-included in this distribution is provided under other licenses. Please visit
-"about:credits" in a CEF-based application for complete Chromium and third-party
-licensing information.
diff --git a/src/bin/SharpBrowser.exe b/src/bin/SharpBrowser.exe
deleted file mode 100644
index 16419ef..0000000
Binary files a/src/bin/SharpBrowser.exe and /dev/null differ
diff --git a/src/bin/SharpBrowser.exe.config b/src/bin/SharpBrowser.exe.config
deleted file mode 100644
index e8419f3..0000000
--- a/src/bin/SharpBrowser.exe.config
+++ /dev/null
@@ -1,10 +0,0 @@
-
-
-
-
-
-
-
-
-
-
diff --git a/src/bin/TabStrip.dll b/src/bin/TabStrip.dll
deleted file mode 100644
index b7011b5..0000000
Binary files a/src/bin/TabStrip.dll and /dev/null differ
diff --git a/src/bin/cef.pak b/src/bin/cef.pak
deleted file mode 100644
index e4bd744..0000000
Binary files a/src/bin/cef.pak and /dev/null differ
diff --git a/src/bin/cef_100_percent.pak b/src/bin/cef_100_percent.pak
deleted file mode 100644
index 68777a7..0000000
Binary files a/src/bin/cef_100_percent.pak and /dev/null differ
diff --git a/src/bin/cef_200_percent.pak b/src/bin/cef_200_percent.pak
deleted file mode 100644
index 665cb3f..0000000
Binary files a/src/bin/cef_200_percent.pak and /dev/null differ
diff --git a/src/bin/cef_extensions.pak b/src/bin/cef_extensions.pak
deleted file mode 100644
index 3c0e271..0000000
Binary files a/src/bin/cef_extensions.pak and /dev/null differ
diff --git a/src/bin/chrome_elf.dll b/src/bin/chrome_elf.dll
deleted file mode 100644
index b8374ef..0000000
Binary files a/src/bin/chrome_elf.dll and /dev/null differ
diff --git a/src/bin/d3dcompiler_47.dll b/src/bin/d3dcompiler_47.dll
deleted file mode 100644
index dbfe9ce..0000000
Binary files a/src/bin/d3dcompiler_47.dll and /dev/null differ
diff --git a/src/bin/debug.log b/src/bin/debug.log
deleted file mode 100644
index 328f868..0000000
--- a/src/bin/debug.log
+++ /dev/null
@@ -1,1369 +0,0 @@
-[1012/184414:ERROR:angle_platform_impl.cc(33)] ANGLE Display::initialize error 5: DXGI 1.2 required to present to HWNDs owned by another process.
-[1012/184414:ERROR:gl_surface_egl.cc(594)] eglInitialize D3D11 failed with error EGL_NOT_INITIALIZED, trying next display type
-[0328/122016:WARNING:backend_impl.cc(1807)] Destroying invalid entry.
-[0328/122022:ERROR:ipc_channel_win.cc(217)] pipe error: 109
-[0328/122113:WARNING:backend_impl.cc(1807)] Destroying invalid entry.
-[0328/122118:ERROR:ipc_channel_win.cc(217)] pipe error: 109
-[0328/122139:WARNING:backend_impl.cc(1807)] Destroying invalid entry.
-[0328/122200:ERROR:ipc_channel_win.cc(217)] pipe error: 109
-[0328/122319:ERROR:ipc_channel_win.cc(217)] pipe error: 109
-[0328/123733:ERROR:webgraphicscontext3d_command_buffer_impl.cc(199)] CommandBufferProxy::Initialize failed.
-[0328/123733:ERROR:webgraphicscontext3d_command_buffer_impl.cc(218)] Failed to initialize command buffer.
-[0328/124449:INFO:CONSOLE(0)] "Unrecognized Content-Security-Policy directive 'require-sri-for'.
-", source: https://securityheaders.io/ (0)
-[0328/124449:INFO:CONSOLE(0)] "The Content Security Policy directive 'upgrade-insecure-requests' is ignored when delivered in a report-only policy.", source: https://securityheaders.io/ (0)
-[0328/124452:ERROR:ipc_channel_win.cc(217)] pipe error: 109
-[0328/124522:INFO:CONSOLE(0)] "Failed to execute 'write' on 'Document': It isn't possible to write into a document from an asynchronously-loaded external script unless it is explicitly opened.", source: https://googleads.g.doubleclick.net/pagead/ads?client=ca-pub-3857768109978969&format=970x250&output=html&h=250&slotname=2836339934&adk=1475818235&adf=193337325&w=970&lmt=1490685321&loeid=26835105&flash=0&url=http%3A%2F%2Frequest.urih.com%2F&wgl=1&dt=1490685321628&bpp=34&bdt=179&fdt=39&idt=111&shv=r20170320&cbv=r20170110&saldr=aa&correlator=7517660423894&frm=20&ga_vid=1371772552.1490685322&ga_sid=1490685322&ga_hid=1997737643&ga_fc=0&pv=2&iag=3&icsg=2&nhd=1&dssz=2&mdo=0&mso=0&u_tz=330&u_his=1&u_java=0&u_h=1920&u_w=1080&u_ah=1920&u_aw=1006&u_cd=24&u_nplug=2&u_nmime=2&adx=17&ady=103&biw=1004&bih=1813&eid=575144605&oid=3&ref=https%3A%2F%2Fwww.google.co.in%2F&rx=0&eae=0&fc=16&brdim=75%2C86%2C75%2C86%2C1006%2C0%2C1004%2C1813%2C1004%2C1813&vis=1&rsz=%7C%7CeoE%7C&abl=CS&ppjl=u&pfx=0&fu=16&bc=1&ifi=1&xpc=HHSMcRHV8w&p=http%3A//request.urih.com&dtd=149 (0)
-[0328/124523:INFO:CONSOLE(1)] "BB-DC -- initiated", source: https://s0.2mdn.net/ads/richmedia/studio/pv2/47183407/20170105133859391/google_sonic-cars_300x250/bannerboy_dc.min.js (1)
-[0328/124524:INFO:CONSOLE(1)] "BB-DC -- polite load", source: https://s0.2mdn.net/ads/richmedia/studio/pv2/47183407/20170105133859391/google_sonic-cars_300x250/bannerboy_dc.min.js (1)
-[0328/124524:INFO:CONSOLE(1)] "BB-DC -- banner is visible", source: https://s0.2mdn.net/ads/richmedia/studio/pv2/47183407/20170105133859391/google_sonic-cars_300x250/bannerboy_dc.min.js (1)
-[0328/124524:INFO:CONSOLE(137)] "[object HTMLDivElement]", source: https://s0.2mdn.net/ads/richmedia/studio/pv2/47183407/20170105133859391/google_sonic-cars_300x250/animation.js (137)
-[0328/124557:INFO:CONSOLE(0)] "Failed to execute 'write' on 'Document': It isn't possible to write into a document from an asynchronously-loaded external script unless it is explicitly opened.", source: https://googleads.g.doubleclick.net/pagead/ads?client=ca-pub-3857768109978969&format=970x250&output=html&h=250&slotname=2836339934&adk=1475818235&adf=193337325&w=970&lmt=1490685356&flash=0&url=http%3A%2F%2Frequest.urih.com%2F&wgl=1&dt=1490685356688&bpp=32&bdt=259&fdt=77&idt=125&shv=r20170320&cbv=r20170110&saldr=aa&correlator=7619512995676&frm=20&ga_vid=315270585.1490685357&ga_sid=1490685357&ga_hid=2138582690&ga_fc=0&pv=2&iag=3&icsg=2&nhd=1&dssz=2&mdo=0&mso=0&u_tz=330&u_his=1&u_java=0&u_h=1920&u_w=1080&u_ah=1920&u_aw=1006&u_cd=24&u_nplug=2&u_nmime=2&adx=17&ady=103&biw=1004&bih=1813&eid=575144605&oid=3&ref=https%3A%2F%2Fwww.google.co.in%2F&rx=0&eae=0&fc=16&brdim=75%2C86%2C75%2C86%2C1006%2C0%2C1004%2C1813%2C1004%2C1813&vis=1&rsz=%7C%7CeoE%7C&abl=CS&ppjl=t&pfx=0&fu=16&bc=1&ifi=1&xpc=IKWsOhsE5W&p=http%3A//request.urih.com&dtd=166 (0)
-[0328/124605:INFO:CONSOLE(0)] "Failed to execute 'write' on 'Document': It isn't possible to write into a document from an asynchronously-loaded external script unless it is explicitly opened.", source: https://googleads.g.doubleclick.net/pagead/ads?client=ca-pub-3857768109978969&format=970x250&output=html&h=250&slotname=2836339934&adk=1475818235&adf=193337325&w=970&lmt=1490685365&flash=0&url=http%3A%2F%2Frequest.urih.com%2F&wgl=1&dt=1490685364897&bpp=32&bdt=63&fdt=41&idt=140&shv=r20170320&cbv=r20170110&saldr=aa&correlator=5893635832733&frm=20&ga_vid=1085384014.1490685365&ga_sid=1490685365&ga_hid=1912761034&ga_fc=0&pv=2&iag=3&icsg=2&nhd=1&dssz=2&mdo=0&mso=0&u_tz=330&u_his=1&u_java=0&u_h=1920&u_w=1080&u_ah=1920&u_aw=1006&u_cd=24&u_nplug=2&u_nmime=2&adx=17&ady=103&biw=1004&bih=1813&eid=575144605%2C828064250&oid=3&ref=https%3A%2F%2Fwww.google.co.in%2F&rx=0&eae=0&fc=16&brdim=75%2C86%2C75%2C86%2C1006%2C0%2C1004%2C1813%2C1004%2C1813&vis=1&rsz=%7C%7CeoE%7C&abl=CS&ppjl=t&pfx=0&fu=16&bc=1&ifi=1&xpc=5b1Zi7rviW&p=http%3A//request.urih.com&dtd=212 (0)
-[0328/124623:ERROR:ipc_channel_win.cc(482)] pipe error: 109
-[0328/124658:INFO:CONSOLE(0)] "Failed to execute 'write' on 'Document': It isn't possible to write into a document from an asynchronously-loaded external script unless it is explicitly opened.", source: https://googleads.g.doubleclick.net/pagead/ads?client=ca-pub-3857768109978969&format=970x250&output=html&h=250&slotname=2836339934&adk=1475818235&adf=193337325&w=970&lmt=1490685418&loeid=389613000&flash=0&url=http%3A%2F%2Frequest.urih.com%2F&wgl=1&dt=1490685418093&bpp=31&bdt=86&fdt=38&idt=81&shv=r20170320&cbv=r20170110&saldr=aa&correlator=2295580802002&frm=20&ga_vid=1091680816.1490685418&ga_sid=1490685418&ga_hid=710277378&ga_fc=0&pv=2&iag=3&icsg=2&nhd=1&dssz=2&mdo=0&mso=0&u_tz=330&u_his=1&u_java=0&u_h=1920&u_w=1080&u_ah=1920&u_aw=1006&u_cd=24&u_nplug=2&u_nmime=2&adx=17&ady=103&biw=1004&bih=1813&eid=4089037%2C575144605&oid=3&ref=https%3A%2F%2Fwww.google.co.in%2F&rx=0&eae=0&fc=16&brdim=75%2C86%2C75%2C86%2C1006%2C0%2C1004%2C1813%2C1004%2C1813&vis=1&rsz=%7C%7CeoE%7C&abl=CS&ppjl=t&pfx=0&fu=16&bc=1&ifi=1&xpc=adHvfHnO2N&p=http%3A//request.urih.com&dtd=119 (0)
-[0328/124731:INFO:CONSOLE(0)] "Failed to execute 'write' on 'Document': It isn't possible to write into a document from an asynchronously-loaded external script unless it is explicitly opened.", source: https://googleads.g.doubleclick.net/pagead/ads?client=ca-pub-3857768109978969&format=970x250&output=html&h=250&slotname=2836339934&adk=1475818235&adf=193337325&w=970&lmt=1490685450&loeid=26835106&flash=0&url=http%3A%2F%2Frequest.urih.com%2F&wgl=1&dt=1490685450505&bpp=21&bdt=379&fdt=27&idt=67&shv=r20170320&cbv=r20170110&saldr=aa&correlator=2538953685609&frm=20&ga_vid=79990598.1490685451&ga_sid=1490685451&ga_hid=497228513&ga_fc=0&pv=2&iag=3&icsg=2&nhd=1&dssz=2&mdo=0&mso=0&u_tz=330&u_his=1&u_java=0&u_h=1920&u_w=1080&u_ah=1920&u_aw=1006&u_cd=24&u_nplug=2&u_nmime=2&adx=17&ady=103&biw=1004&bih=1813&eid=575144605%2C20040041&oid=3&ref=https%3A%2F%2Fwww.google.co.in%2F&rx=0&eae=0&fc=16&brdim=75%2C86%2C75%2C86%2C1006%2C0%2C1004%2C1813%2C1004%2C1813&vis=1&rsz=%7C%7CeoE%7C&abl=CS&ppjl=t&pfx=0&fu=16&bc=1&ifi=1&xpc=Fa6aVQgJvW&p=http%3A//request.urih.com&dtd=106 (0)
-[0328/124814:INFO:CONSOLE(0)] "Failed to execute 'write' on 'Document': It isn't possible to write into a document from an asynchronously-loaded external script unless it is explicitly opened.", source: https://googleads.g.doubleclick.net/pagead/ads?client=ca-pub-3857768109978969&format=970x250&output=html&h=250&slotname=2836339934&adk=1475818235&adf=193337325&w=970&lmt=1490685493&flash=0&url=http%3A%2F%2Frequest.urih.com%2F&wgl=1&dt=1490685493622&bpp=32&bdt=95&fdt=44&idt=113&shv=r20170320&cbv=r20170110&saldr=aa&correlator=8174823808537&frm=20&ga_vid=1494649478.1490685494&ga_sid=1490685494&ga_hid=111005926&ga_fc=0&pv=2&iag=3&icsg=2&nhd=1&dssz=2&mdo=0&mso=0&u_tz=330&u_his=1&u_java=0&u_h=1920&u_w=1080&u_ah=1920&u_aw=1006&u_cd=24&u_nplug=2&u_nmime=2&adx=17&ady=103&biw=1004&bih=1813&eid=575144605&oid=3&ref=https%3A%2F%2Fwww.google.co.in%2F&rx=0&eae=0&fc=16&brdim=75%2C86%2C75%2C86%2C1006%2C0%2C1004%2C1813%2C1004%2C1813&vis=1&rsz=%7C%7CeoE%7C&abl=CS&ppjl=t&pfx=0&fu=16&bc=1&ifi=1&xpc=d0RmTdtanE&p=http%3A//request.urih.com&dtd=151 (0)
-[0328/124814:INFO:CONSOLE(1)] "BB-DC -- initiated", source: https://s0.2mdn.net/ads/richmedia/studio/pv2/47185306/20170105133851130/google_sonic-bar-chart_300x250/bannerboy_dc.min.js (1)
-[0328/124815:INFO:CONSOLE(1)] "BB-DC -- polite load", source: https://s0.2mdn.net/ads/richmedia/studio/pv2/47185306/20170105133851130/google_sonic-bar-chart_300x250/bannerboy_dc.min.js (1)
-[0328/124815:INFO:CONSOLE(1)] "BB-DC -- banner is visible", source: https://s0.2mdn.net/ads/richmedia/studio/pv2/47185306/20170105133851130/google_sonic-bar-chart_300x250/bannerboy_dc.min.js (1)
-[0328/124855:INFO:CONSOLE(0)] "Failed to execute 'write' on 'Document': It isn't possible to write into a document from an asynchronously-loaded external script unless it is explicitly opened.", source: https://googleads.g.doubleclick.net/pagead/ads?client=ca-pub-3857768109978969&format=970x250&output=html&h=250&slotname=2836339934&adk=1475818235&adf=193337325&w=970&lmt=1490685534&flash=0&url=http%3A%2F%2Frequest.urih.com%2F&wgl=1&dt=1490685534472&bpp=16&bdt=138&fdt=19&idt=65&shv=r20170320&cbv=r20170110&saldr=aa&correlator=5607521407751&frm=20&ga_vid=1201419210.1490685535&ga_sid=1490685535&ga_hid=1083680859&ga_fc=0&pv=2&iag=3&icsg=2&nhd=1&dssz=2&mdo=0&mso=0&u_tz=330&u_his=1&u_java=0&u_h=1920&u_w=1080&u_ah=1920&u_aw=1006&u_cd=24&u_nplug=2&u_nmime=2&adx=17&ady=103&biw=1004&bih=1813&eid=575144605&oid=3&ref=https%3A%2F%2Fwww.google.co.in%2F&rx=0&eae=0&fc=16&brdim=75%2C86%2C75%2C86%2C1006%2C0%2C1004%2C1813%2C1004%2C1813&vis=1&rsz=%7C%7CeoE%7C&abl=CS&ppjl=t&pfx=0&fu=16&bc=1&ifi=1&xpc=so0eGhSyWR&p=http%3A//request.urih.com&dtd=109 (0)
-[0328/125112:WARNING:extension_protocols.cc(438)] Failed to GetPathForExtension: pkedcjkdefgpdelpbcmbmeomcjbeemfm
-[0328/125112:WARNING:url_request_job_manager.cc(89)] Failed to map: chrome-extension://pkedcjkdefgpdelpbcmbmeomcjbeemfm/cast_sender.js
-[0328/125112:WARNING:extension_protocols.cc(438)] Failed to GetPathForExtension: fjhoaacokmgbjemoflkofnenfaiekifl
-[0328/125112:WARNING:url_request_job_manager.cc(89)] Failed to map: chrome-extension://fjhoaacokmgbjemoflkofnenfaiekifl/cast_sender.js
-[0328/125112:INFO:CONSOLE(0)] "Mixed Content: The page at 'https://www.youtube.com/watch?v=YQHsXMglC9A' was loaded over HTTPS, but requested an insecure script 'sharpbrowser://storage/errors/cannotConnect.html'. This request has been blocked; the content must be served over HTTPS.", source: https://www.youtube.com/watch?v=YQHsXMglC9A (0)
-[0328/125112:INFO:CONSOLE(0)] "Mixed Content: The page at 'https://www.youtube.com/watch?v=YQHsXMglC9A' was loaded over HTTPS, but requested an insecure script 'sharpbrowser://storage/errors/cannotConnect.html'. This request has been blocked; the content must be served over HTTPS.", source: https://www.youtube.com/watch?v=YQHsXMglC9A (0)
-[0328/125112:WARNING:extension_protocols.cc(438)] Failed to GetPathForExtension: boadgeojelhgndaghljhdicfkmllpafd
-[0328/125113:WARNING:url_request_job_manager.cc(89)] Failed to map: chrome-extension://boadgeojelhgndaghljhdicfkmllpafd/cast_sender.js
-[0328/125113:INFO:CONSOLE(0)] "Mixed Content: The page at 'https://www.youtube.com/watch?v=YQHsXMglC9A' was loaded over HTTPS, but requested an insecure XMLHttpRequest endpoint 'sharpbrowser://storage/errors/cannotConnect.html'. This request has been blocked; the content must be served over HTTPS.", source: https://www.youtube.com/watch?v=YQHsXMglC9A (0)
-[0328/125113:WARNING:extension_protocols.cc(438)] Failed to GetPathForExtension: dliochdbjfkdbacpmhlcpmleaejidimm
-[0328/125113:WARNING:url_request_job_manager.cc(89)] Failed to map: chrome-extension://dliochdbjfkdbacpmhlcpmleaejidimm/cast_sender.js
-[0328/125113:INFO:CONSOLE(0)] "Mixed Content: The page at 'https://www.youtube.com/watch?v=YQHsXMglC9A' was loaded over HTTPS, but requested an insecure XMLHttpRequest endpoint 'sharpbrowser://storage/errors/cannotConnect.html'. This request has been blocked; the content must be served over HTTPS.", source: https://www.youtube.com/watch?v=YQHsXMglC9A (0)
-[0328/125113:WARNING:extension_protocols.cc(438)] Failed to GetPathForExtension: enhhojjnijigcajfphajepfemndkmdlo
-[0328/125113:WARNING:url_request_job_manager.cc(89)] Failed to map: chrome-extension://enhhojjnijigcajfphajepfemndkmdlo/cast_sender.js
-[0328/125113:INFO:CONSOLE(0)] "Mixed Content: The page at 'https://www.youtube.com/watch?v=YQHsXMglC9A' was loaded over HTTPS, but requested an insecure XMLHttpRequest endpoint 'sharpbrowser://storage/errors/cannotConnect.html'. This request has been blocked; the content must be served over HTTPS.", source: https://www.youtube.com/watch?v=YQHsXMglC9A (0)
-[0328/125113:WARNING:extension_protocols.cc(438)] Failed to GetPathForExtension: fmfcbgogabcbclcofgocippekhfcmgfj
-[0328/125113:WARNING:url_request_job_manager.cc(89)] Failed to map: chrome-extension://fmfcbgogabcbclcofgocippekhfcmgfj/cast_sender.js
-[0328/125113:ERROR:gpu_video_decode_accelerator.cc(362)] HW video decode not available for profile 12
-[0328/125113:INFO:CONSOLE(0)] "Mixed Content: The page at 'https://www.youtube.com/watch?v=YQHsXMglC9A' was loaded over HTTPS, but requested an insecure XMLHttpRequest endpoint 'sharpbrowser://storage/errors/cannotConnect.html'. This request has been blocked; the content must be served over HTTPS.", source: https://www.youtube.com/watch?v=YQHsXMglC9A (0)
-[0328/125114:INFO:CONSOLE(548)] "Uncaught (in promise) TypeError: Cannot read property 'permission' of undefined", source: https://www.youtube.com/yts/jsbin/www-en_US-vflG_bpHk/base.js (548)
-[0328/125117:ERROR:gpu_video_decode_accelerator.cc(362)] HW video decode not available for profile 12
-[0328/125117:INFO:CONSOLE(548)] "Uncaught (in promise) TypeError: Cannot read property 'permission' of undefined", source: https://www.youtube.com/yts/jsbin/www-en_US-vflG_bpHk/base.js (548)
-[0328/125120:ERROR:ipc_channel_win.cc(217)] pipe error: 109
-[0328/125122:INFO:CONSOLE(0)] "Mixed Content: The page at 'https://www.youtube.com/watch?v=hLQl3WQQoQ0' was loaded over HTTPS, but requested an insecure resource 'sharpbrowser://storage/errors/cannotConnect.html'. This content should also be served over HTTPS.", source: https://www.youtube.com/watch?v=hLQl3WQQoQ0 (0)
-[0328/125126:WARNING:extension_protocols.cc(438)] Failed to GetPathForExtension: pkedcjkdefgpdelpbcmbmeomcjbeemfm
-[0328/125126:WARNING:url_request_job_manager.cc(89)] Failed to map: chrome-extension://pkedcjkdefgpdelpbcmbmeomcjbeemfm/cast_sender.js
-[0328/125126:WARNING:extension_protocols.cc(438)] Failed to GetPathForExtension: fjhoaacokmgbjemoflkofnenfaiekifl
-[0328/125126:WARNING:url_request_job_manager.cc(89)] Failed to map: chrome-extension://fjhoaacokmgbjemoflkofnenfaiekifl/cast_sender.js
-[0328/125126:INFO:CONSOLE(0)] "Mixed Content: The page at 'https://www.youtube.com/watch?v=hLQl3WQQoQ0' was loaded over HTTPS, but requested an insecure script 'sharpbrowser://storage/errors/cannotConnect.html'. This request has been blocked; the content must be served over HTTPS.", source: https://www.youtube.com/watch?v=hLQl3WQQoQ0 (0)
-[0328/125126:INFO:CONSOLE(0)] "Mixed Content: The page at 'https://www.youtube.com/watch?v=hLQl3WQQoQ0' was loaded over HTTPS, but requested an insecure script 'sharpbrowser://storage/errors/cannotConnect.html'. This request has been blocked; the content must be served over HTTPS.", source: https://www.youtube.com/watch?v=hLQl3WQQoQ0 (0)
-[0328/125126:WARNING:extension_protocols.cc(438)] Failed to GetPathForExtension: boadgeojelhgndaghljhdicfkmllpafd
-[0328/125126:WARNING:url_request_job_manager.cc(89)] Failed to map: chrome-extension://boadgeojelhgndaghljhdicfkmllpafd/cast_sender.js
-[0328/125126:INFO:CONSOLE(0)] "Mixed Content: The page at 'https://www.youtube.com/watch?v=hLQl3WQQoQ0' was loaded over HTTPS, but requested an insecure XMLHttpRequest endpoint 'sharpbrowser://storage/errors/cannotConnect.html'. This request has been blocked; the content must be served over HTTPS.", source: https://www.youtube.com/watch?v=hLQl3WQQoQ0 (0)
-[0328/125126:WARNING:extension_protocols.cc(438)] Failed to GetPathForExtension: dliochdbjfkdbacpmhlcpmleaejidimm
-[0328/125126:WARNING:url_request_job_manager.cc(89)] Failed to map: chrome-extension://dliochdbjfkdbacpmhlcpmleaejidimm/cast_sender.js
-[0328/125126:INFO:CONSOLE(0)] "Mixed Content: The page at 'https://www.youtube.com/watch?v=hLQl3WQQoQ0' was loaded over HTTPS, but requested an insecure XMLHttpRequest endpoint 'sharpbrowser://storage/errors/cannotConnect.html'. This request has been blocked; the content must be served over HTTPS.", source: https://www.youtube.com/watch?v=hLQl3WQQoQ0 (0)
-[0328/125126:WARNING:extension_protocols.cc(438)] Failed to GetPathForExtension: enhhojjnijigcajfphajepfemndkmdlo
-[0328/125126:WARNING:url_request_job_manager.cc(89)] Failed to map: chrome-extension://enhhojjnijigcajfphajepfemndkmdlo/cast_sender.js
-[0328/125126:INFO:CONSOLE(0)] "Mixed Content: The page at 'https://www.youtube.com/watch?v=hLQl3WQQoQ0' was loaded over HTTPS, but requested an insecure XMLHttpRequest endpoint 'sharpbrowser://storage/errors/cannotConnect.html'. This request has been blocked; the content must be served over HTTPS.", source: https://www.youtube.com/watch?v=hLQl3WQQoQ0 (0)
-[0328/125126:WARNING:extension_protocols.cc(438)] Failed to GetPathForExtension: fmfcbgogabcbclcofgocippekhfcmgfj
-[0328/125126:WARNING:url_request_job_manager.cc(89)] Failed to map: chrome-extension://fmfcbgogabcbclcofgocippekhfcmgfj/cast_sender.js
-[0328/125126:ERROR:gpu_video_decode_accelerator.cc(362)] HW video decode not available for profile 12
-[0328/125126:INFO:CONSOLE(0)] "Mixed Content: The page at 'https://www.youtube.com/watch?v=hLQl3WQQoQ0' was loaded over HTTPS, but requested an insecure XMLHttpRequest endpoint 'sharpbrowser://storage/errors/cannotConnect.html'. This request has been blocked; the content must be served over HTTPS.", source: https://www.youtube.com/watch?v=hLQl3WQQoQ0 (0)
-[0328/125127:INFO:CONSOLE(548)] "Uncaught (in promise) TypeError: Cannot read property 'permission' of undefined", source: https://www.youtube.com/yts/jsbin/www-en_US-vflG_bpHk/base.js (548)
-[0328/125137:WARNING:extension_protocols.cc(438)] Failed to GetPathForExtension: pkedcjkdefgpdelpbcmbmeomcjbeemfm
-[0328/125137:WARNING:url_request_job_manager.cc(89)] Failed to map: chrome-extension://pkedcjkdefgpdelpbcmbmeomcjbeemfm/cast_sender.js
-[0328/125137:INFO:CONSOLE(0)] "Mixed Content: The page at 'https://www.youtube.com/watch?v=Ri7-vnrJD3k' was loaded over HTTPS, but requested an insecure script 'sharpbrowser://storage/errors/cannotConnect.html'. This request has been blocked; the content must be served over HTTPS.", source: https://www.youtube.com/watch?v=Ri7-vnrJD3k (0)
-[0328/125137:WARNING:extension_protocols.cc(438)] Failed to GetPathForExtension: fjhoaacokmgbjemoflkofnenfaiekifl
-[0328/125137:WARNING:url_request_job_manager.cc(89)] Failed to map: chrome-extension://fjhoaacokmgbjemoflkofnenfaiekifl/cast_sender.js
-[0328/125137:WARNING:extension_protocols.cc(438)] Failed to GetPathForExtension: boadgeojelhgndaghljhdicfkmllpafd
-[0328/125137:WARNING:url_request_job_manager.cc(89)] Failed to map: chrome-extension://boadgeojelhgndaghljhdicfkmllpafd/cast_sender.js
-[0328/125137:INFO:CONSOLE(0)] "Mixed Content: The page at 'https://www.youtube.com/watch?v=Ri7-vnrJD3k' was loaded over HTTPS, but requested an insecure script 'sharpbrowser://storage/errors/cannotConnect.html'. This request has been blocked; the content must be served over HTTPS.", source: https://www.youtube.com/watch?v=Ri7-vnrJD3k (0)
-[0328/125137:WARNING:extension_protocols.cc(438)] Failed to GetPathForExtension: dliochdbjfkdbacpmhlcpmleaejidimm
-[0328/125137:WARNING:url_request_job_manager.cc(89)] Failed to map: chrome-extension://dliochdbjfkdbacpmhlcpmleaejidimm/cast_sender.js
-[0328/125137:INFO:CONSOLE(0)] "Mixed Content: The page at 'https://www.youtube.com/watch?v=Ri7-vnrJD3k' was loaded over HTTPS, but requested an insecure XMLHttpRequest endpoint 'sharpbrowser://storage/errors/cannotConnect.html'. This request has been blocked; the content must be served over HTTPS.", source: https://www.youtube.com/watch?v=Ri7-vnrJD3k (0)
-[0328/125137:INFO:CONSOLE(0)] "Mixed Content: The page at 'https://www.youtube.com/watch?v=Ri7-vnrJD3k' was loaded over HTTPS, but requested an insecure XMLHttpRequest endpoint 'sharpbrowser://storage/errors/cannotConnect.html'. This request has been blocked; the content must be served over HTTPS.", source: https://www.youtube.com/watch?v=Ri7-vnrJD3k (0)
-[0328/125137:WARNING:extension_protocols.cc(438)] Failed to GetPathForExtension: enhhojjnijigcajfphajepfemndkmdlo
-[0328/125137:WARNING:url_request_job_manager.cc(89)] Failed to map: chrome-extension://enhhojjnijigcajfphajepfemndkmdlo/cast_sender.js
-[0328/125137:ERROR:gpu_video_decode_accelerator.cc(362)] HW video decode not available for profile 12
-[0328/125137:WARNING:extension_protocols.cc(438)] Failed to GetPathForExtension: fmfcbgogabcbclcofgocippekhfcmgfj
-[0328/125137:WARNING:url_request_job_manager.cc(89)] Failed to map: chrome-extension://fmfcbgogabcbclcofgocippekhfcmgfj/cast_sender.js
-[0328/125137:INFO:CONSOLE(0)] "Mixed Content: The page at 'https://www.youtube.com/watch?v=Ri7-vnrJD3k' was loaded over HTTPS, but requested an insecure XMLHttpRequest endpoint 'sharpbrowser://storage/errors/cannotConnect.html'. This request has been blocked; the content must be served over HTTPS.", source: https://www.youtube.com/watch?v=Ri7-vnrJD3k (0)
-[0328/125137:INFO:CONSOLE(0)] "Mixed Content: The page at 'https://www.youtube.com/watch?v=Ri7-vnrJD3k' was loaded over HTTPS, but requested an insecure XMLHttpRequest endpoint 'sharpbrowser://storage/errors/cannotConnect.html'. This request has been blocked; the content must be served over HTTPS.", source: https://www.youtube.com/watch?v=Ri7-vnrJD3k (0)
-[0328/125138:INFO:CONSOLE(548)] "Uncaught (in promise) TypeError: Cannot read property 'permission' of undefined", source: https://www.youtube.com/yts/jsbin/www-en_US-vflG_bpHk/base.js (548)
-[0328/125139:ERROR:ipc_channel_win.cc(217)] pipe error: 109
-[0328/125142:ERROR:gpu_video_decode_accelerator.cc(362)] HW video decode not available for profile 12
-[0328/125148:ERROR:ipc_channel_win.cc(217)] pipe error: 109
-[0328/125208:ERROR:gpu_video_decode_accelerator.cc(362)] HW video decode not available for profile 12
-[0328/125209:ERROR:ipc_channel_win.cc(519)] pipe error: 232
-[0328/125209:ERROR:ipc_channel_win.cc(519)] pipe error: 232
-[0328/125209:ERROR:ipc_channel_win.cc(519)] pipe error: 232
-[0328/125209:ERROR:ipc_channel_win.cc(519)] pipe error: 232
-[0328/125209:ERROR:ipc_channel_win.cc(519)] pipe error: 232
-[0328/125209:ERROR:ipc_channel_win.cc(217)] pipe error: 109
-[0328/125219:ERROR:render_media_log.cc(23)] MediaEvent: PIPELINE_ERROR demuxer: could not open
-[0328/125219:ERROR:render_media_log.cc(23)] MediaEvent: PIPELINE_ERROR demuxer: could not open
-[0328/125219:ERROR:render_media_log.cc(23)] MediaEvent: PIPELINE_ERROR demuxer: could not open
-[0328/125219:ERROR:render_media_log.cc(23)] MediaEvent: PIPELINE_ERROR demuxer: could not open
-[0328/125219:ERROR:render_media_log.cc(23)] MediaEvent: PIPELINE_ERROR demuxer: could not open
-[0328/125219:ERROR:render_media_log.cc(23)] MediaEvent: PIPELINE_ERROR demuxer: could not open
-[0328/125224:INFO:CONSOLE(3)] "Timeout has been reached for bid with slot", source: http://vlibs.advertising.com/one-publishers-api/PubTag/pubtaglib-0.x.x.js (3)
-[0328/125224:INFO:CONSOLE(3)] "Timeout has been reached for bid with slot", source: http://vlibs.advertising.com/one-publishers-api/PubTag/pubtaglib-0.x.x.js (3)
-[0328/125224:INFO:CONSOLE(3)] "Timeout has been reached for bid with slot", source: http://vlibs.advertising.com/one-publishers-api/PubTag/pubtaglib-0.x.x.js (3)
-[0328/125224:INFO:CONSOLE(3)] "Timeout has been reached for bid with slot", source: http://vlibs.advertising.com/one-publishers-api/PubTag/pubtaglib-0.x.x.js (3)
-[0328/125224:INFO:CONSOLE(3)] "Timeout has been reached for bid with slot", source: http://vlibs.advertising.com/one-publishers-api/PubTag/pubtaglib-0.x.x.js (3)
-[0328/125224:INFO:CONSOLE(3)] "Timeout has been reached for bid with slot", source: http://vlibs.advertising.com/one-publishers-api/PubTag/pubtaglib-0.x.x.js (3)
-[0328/125224:INFO:CONSOLE(3)] "Timeout has been reached for bid with slot", source: http://vlibs.advertising.com/one-publishers-api/PubTag/pubtaglib-0.x.x.js (3)
-[0328/125228:ERROR:ipc_channel_win.cc(519)] pipe error: 232
-[0328/125228:ERROR:ipc_channel_win.cc(217)] pipe error: 109
-[0222/112345.924:WARNING:resource_bundle.cc(929)] unable to find resource: 163
-[0222/112346.634:WARNING:resource_bundle.cc(929)] unable to find resource: 120
-[0222/112346.635:WARNING:resource_bundle.cc(929)] unable to find resource: 121
-[0222/112346.979:WARNING:resource_bundle.cc(929)] unable to find resource: 122
-[0222/112346.979:WARNING:resource_bundle.cc(929)] unable to find resource: 123
-[0222/112346.980:WARNING:resource_bundle.cc(929)] unable to find resource: 123
-[0222/112346.980:WARNING:resource_bundle.cc(929)] unable to find resource: 125
-[0222/112346.981:WARNING:resource_bundle.cc(929)] unable to find resource: 126
-[0222/112346.982:WARNING:resource_bundle.cc(929)] unable to find resource: 127
-[0222/112346.983:WARNING:resource_bundle.cc(929)] unable to find resource: 128
-[0222/112346.983:WARNING:resource_bundle.cc(929)] unable to find resource: 129
-[0222/112346.985:WARNING:resource_bundle.cc(929)] unable to find resource: 130
-[0222/112346.985:WARNING:resource_bundle.cc(929)] unable to find resource: 131
-[0222/112346.986:WARNING:resource_bundle.cc(929)] unable to find resource: 132
-[0222/112346.989:WARNING:resource_bundle.cc(929)] unable to find resource: 133
-[0222/112346.990:WARNING:resource_bundle.cc(929)] unable to find resource: 134
-[0222/112346.991:WARNING:resource_bundle.cc(929)] unable to find resource: 135
-[0222/112346.993:WARNING:resource_bundle.cc(929)] unable to find resource: 136
-[0222/112346.993:WARNING:resource_bundle.cc(929)] unable to find resource: 137
-[0222/112346.994:WARNING:resource_bundle.cc(929)] unable to find resource: 138
-[0222/112346.995:WARNING:resource_bundle.cc(929)] unable to find resource: 139
-[0222/112346.996:WARNING:resource_bundle.cc(929)] unable to find resource: 140
-[0222/112346.997:WARNING:resource_bundle.cc(929)] unable to find resource: 141
-[0222/112346.998:WARNING:resource_bundle.cc(929)] unable to find resource: 142
-[0222/112346.999:WARNING:resource_bundle.cc(929)] unable to find resource: 143
-[0222/112347.000:WARNING:resource_bundle.cc(929)] unable to find resource: 144
-[0222/112347.003:WARNING:resource_bundle.cc(929)] unable to find resource: 145
-[0222/112347.004:WARNING:resource_bundle.cc(929)] unable to find resource: 146
-[0222/112347.005:WARNING:resource_bundle.cc(929)] unable to find resource: 147
-[0222/112347.006:WARNING:resource_bundle.cc(929)] unable to find resource: 148
-[0222/112347.010:WARNING:resource_bundle.cc(929)] unable to find resource: 149
-[0222/112347.015:WARNING:resource_bundle.cc(929)] unable to find resource: 150
-[0222/112347.016:WARNING:resource_bundle.cc(929)] unable to find resource: 151
-[0222/112347.017:WARNING:resource_bundle.cc(929)] unable to find resource: 152
-[0222/112347.018:WARNING:resource_bundle.cc(929)] unable to find resource: 153
-[0222/112347.021:WARNING:resource_bundle.cc(929)] unable to find resource: 154
-[0222/112347.023:WARNING:resource_bundle.cc(929)] unable to find resource: 155
-[0222/112347.025:WARNING:resource_bundle.cc(929)] unable to find resource: 156
-[0222/112347.027:WARNING:resource_bundle.cc(929)] unable to find resource: 157
-[0222/112347.029:WARNING:resource_bundle.cc(929)] unable to find resource: 158
-[0222/112347.062:WARNING:resource_bundle.cc(929)] unable to find resource: 159
-[0222/112347.062:WARNING:resource_bundle.cc(929)] unable to find resource: 160
-[0222/112347.063:WARNING:resource_bundle.cc(929)] unable to find resource: 161
-[0222/112347.064:WARNING:resource_bundle.cc(929)] unable to find resource: 162
-[0222/112533.072:WARNING:resource_bundle.cc(929)] unable to find resource: 163
-[0222/112533.136:WARNING:resource_bundle.cc(929)] unable to find resource: 120
-[0222/112533.137:WARNING:resource_bundle.cc(929)] unable to find resource: 121
-[0222/112533.176:WARNING:resource_bundle.cc(929)] unable to find resource: 122
-[0222/112533.189:WARNING:resource_bundle.cc(929)] unable to find resource: 123
-[0222/112533.207:WARNING:resource_bundle.cc(929)] unable to find resource: 123
-[0222/112533.227:WARNING:resource_bundle.cc(929)] unable to find resource: 125
-[0222/112533.228:WARNING:resource_bundle.cc(929)] unable to find resource: 126
-[0222/112533.244:WARNING:resource_bundle.cc(929)] unable to find resource: 127
-[0222/112533.256:WARNING:resource_bundle.cc(929)] unable to find resource: 128
-[0222/112533.260:WARNING:resource_bundle.cc(929)] unable to find resource: 129
-[0222/112533.262:WARNING:resource_bundle.cc(929)] unable to find resource: 130
-[0222/112533.263:WARNING:resource_bundle.cc(929)] unable to find resource: 131
-[0222/112533.266:WARNING:resource_bundle.cc(929)] unable to find resource: 132
-[0222/112533.276:WARNING:resource_bundle.cc(929)] unable to find resource: 133
-[0222/112533.284:WARNING:resource_bundle.cc(929)] unable to find resource: 134
-[0222/112533.296:WARNING:resource_bundle.cc(929)] unable to find resource: 135
-[0222/112533.298:WARNING:resource_bundle.cc(929)] unable to find resource: 136
-[0222/112533.302:WARNING:resource_bundle.cc(929)] unable to find resource: 137
-[0222/112533.305:WARNING:resource_bundle.cc(929)] unable to find resource: 138
-[0222/112533.306:WARNING:resource_bundle.cc(929)] unable to find resource: 139
-[0222/112533.310:WARNING:resource_bundle.cc(929)] unable to find resource: 140
-[0222/112533.314:WARNING:resource_bundle.cc(929)] unable to find resource: 141
-[0222/112533.320:WARNING:resource_bundle.cc(929)] unable to find resource: 142
-[0222/112533.324:WARNING:resource_bundle.cc(929)] unable to find resource: 143
-[0222/112533.338:WARNING:resource_bundle.cc(929)] unable to find resource: 144
-[0222/112533.344:WARNING:resource_bundle.cc(929)] unable to find resource: 145
-[0222/112533.356:WARNING:resource_bundle.cc(929)] unable to find resource: 146
-[0222/112533.380:WARNING:resource_bundle.cc(929)] unable to find resource: 147
-[0222/112533.395:WARNING:resource_bundle.cc(929)] unable to find resource: 148
-[0222/112533.423:WARNING:resource_bundle.cc(929)] unable to find resource: 149
-[0222/112533.439:WARNING:resource_bundle.cc(929)] unable to find resource: 150
-[0222/112533.451:WARNING:resource_bundle.cc(929)] unable to find resource: 151
-[0222/112533.452:WARNING:resource_bundle.cc(929)] unable to find resource: 152
-[0222/112533.453:WARNING:resource_bundle.cc(929)] unable to find resource: 153
-[0222/112533.455:WARNING:resource_bundle.cc(929)] unable to find resource: 154
-[0222/112533.470:WARNING:resource_bundle.cc(929)] unable to find resource: 155
-[0222/112533.475:WARNING:resource_bundle.cc(929)] unable to find resource: 156
-[0222/112533.476:WARNING:resource_bundle.cc(929)] unable to find resource: 157
-[0222/112533.480:WARNING:resource_bundle.cc(929)] unable to find resource: 158
-[0222/112533.491:WARNING:resource_bundle.cc(929)] unable to find resource: 159
-[0222/112533.497:WARNING:resource_bundle.cc(929)] unable to find resource: 160
-[0222/112533.500:WARNING:resource_bundle.cc(929)] unable to find resource: 161
-[0222/112533.502:WARNING:resource_bundle.cc(929)] unable to find resource: 162
-[0222/112535.688:WARNING:resource_bundle.cc(929)] unable to find resource: 289
-[0222/112535.694:WARNING:resource_bundle.cc(929)] unable to find resource: 290
-[0222/112551.643:WARNING:resource_bundle.cc(929)] unable to find resource: 194
-[0222/112551.643:WARNING:resource_bundle.cc(929)] unable to find resource: 195
-[0222/112606.032:WARNING:resource_bundle.cc(929)] unable to find resource: 289
-[0222/112606.033:WARNING:resource_bundle.cc(929)] unable to find resource: 290
-[0222/112615.604:INFO:CONSOLE(0)] "Mixed Content: The page at 'https://www.google.com/search?q=whats+up&cad=h' was loaded over HTTPS, but requested an insecure image 'http://web.archive.org/web/*/https://id.google.com/verify/AAp5M_tn_F1puOxNT8OOBRIz3_ggmdzfLtEcDEUAPh4aIJpnO_iLXfLBlur7Q-idTwDHJNfqNWcYQD2EvhOg0UeNZ7tRs8_zYRN6P0yCRypD2N3JcuXp5Qs'. This content should also be served over HTTPS.", source: https://www.google.com/search?q=whats+up&cad=h (0)
-[0222/112745.314:WARNING:resource_bundle.cc(929)] unable to find resource: 163
-[0222/112745.432:WARNING:resource_bundle.cc(929)] unable to find resource: 120
-[0222/112745.474:WARNING:resource_bundle.cc(929)] unable to find resource: 121
-[0222/112745.512:WARNING:resource_bundle.cc(929)] unable to find resource: 122
-[0222/112745.576:WARNING:resource_bundle.cc(929)] unable to find resource: 123
-[0222/112745.604:WARNING:resource_bundle.cc(929)] unable to find resource: 123
-[0222/112745.639:WARNING:resource_bundle.cc(929)] unable to find resource: 125
-[0222/112745.660:WARNING:resource_bundle.cc(929)] unable to find resource: 126
-[0222/112745.675:WARNING:resource_bundle.cc(929)] unable to find resource: 127
-[0222/112745.695:WARNING:resource_bundle.cc(929)] unable to find resource: 128
-[0222/112745.725:WARNING:resource_bundle.cc(929)] unable to find resource: 129
-[0222/112745.733:WARNING:resource_bundle.cc(929)] unable to find resource: 130
-[0222/112745.747:WARNING:resource_bundle.cc(929)] unable to find resource: 131
-[0222/112745.768:WARNING:resource_bundle.cc(929)] unable to find resource: 132
-[0222/112745.770:WARNING:resource_bundle.cc(929)] unable to find resource: 133
-[0222/112745.779:WARNING:resource_bundle.cc(929)] unable to find resource: 134
-[0222/112745.815:WARNING:resource_bundle.cc(929)] unable to find resource: 135
-[0222/112745.818:WARNING:resource_bundle.cc(929)] unable to find resource: 136
-[0222/112745.823:WARNING:resource_bundle.cc(929)] unable to find resource: 137
-[0222/112745.829:WARNING:resource_bundle.cc(929)] unable to find resource: 138
-[0222/112745.831:WARNING:resource_bundle.cc(929)] unable to find resource: 139
-[0222/112745.847:WARNING:resource_bundle.cc(929)] unable to find resource: 140
-[0222/112745.858:WARNING:resource_bundle.cc(929)] unable to find resource: 141
-[0222/112745.862:WARNING:resource_bundle.cc(929)] unable to find resource: 142
-[0222/112745.869:WARNING:resource_bundle.cc(929)] unable to find resource: 143
-[0222/112745.876:WARNING:resource_bundle.cc(929)] unable to find resource: 144
-[0222/112745.879:WARNING:resource_bundle.cc(929)] unable to find resource: 145
-[0222/112745.880:WARNING:resource_bundle.cc(929)] unable to find resource: 146
-[0222/112745.881:WARNING:resource_bundle.cc(929)] unable to find resource: 147
-[0222/112745.882:WARNING:resource_bundle.cc(929)] unable to find resource: 148
-[0222/112745.883:WARNING:resource_bundle.cc(929)] unable to find resource: 149
-[0222/112745.883:WARNING:resource_bundle.cc(929)] unable to find resource: 150
-[0222/112745.884:WARNING:resource_bundle.cc(929)] unable to find resource: 151
-[0222/112745.885:WARNING:resource_bundle.cc(929)] unable to find resource: 152
-[0222/112745.886:WARNING:resource_bundle.cc(929)] unable to find resource: 153
-[0222/112745.887:WARNING:resource_bundle.cc(929)] unable to find resource: 154
-[0222/112745.892:WARNING:resource_bundle.cc(929)] unable to find resource: 155
-[0222/112745.896:WARNING:resource_bundle.cc(929)] unable to find resource: 156
-[0222/112745.902:WARNING:resource_bundle.cc(929)] unable to find resource: 157
-[0222/112745.908:WARNING:resource_bundle.cc(929)] unable to find resource: 158
-[0222/112745.912:WARNING:resource_bundle.cc(929)] unable to find resource: 159
-[0222/112745.915:WARNING:resource_bundle.cc(929)] unable to find resource: 160
-[0222/112745.916:WARNING:resource_bundle.cc(929)] unable to find resource: 161
-[0222/112745.917:WARNING:resource_bundle.cc(929)] unable to find resource: 162
-[0222/112746.697:WARNING:resource_bundle.cc(929)] unable to find resource: 289
-[0222/112746.701:WARNING:resource_bundle.cc(929)] unable to find resource: 290
-[0222/112842.535:WARNING:resource_bundle.cc(929)] unable to find resource: 163
-[0222/112842.707:WARNING:resource_bundle.cc(929)] unable to find resource: 120
-[0222/112842.720:WARNING:resource_bundle.cc(929)] unable to find resource: 121
-[0222/112842.740:WARNING:resource_bundle.cc(929)] unable to find resource: 122
-[0222/112842.762:WARNING:resource_bundle.cc(929)] unable to find resource: 123
-[0222/112842.769:WARNING:resource_bundle.cc(929)] unable to find resource: 123
-[0222/112842.773:WARNING:resource_bundle.cc(929)] unable to find resource: 125
-[0222/112842.790:WARNING:resource_bundle.cc(929)] unable to find resource: 126
-[0222/112842.794:WARNING:resource_bundle.cc(929)] unable to find resource: 127
-[0222/112842.806:WARNING:resource_bundle.cc(929)] unable to find resource: 128
-[0222/112842.809:WARNING:resource_bundle.cc(929)] unable to find resource: 129
-[0222/112842.810:WARNING:resource_bundle.cc(929)] unable to find resource: 130
-[0222/112842.817:WARNING:resource_bundle.cc(929)] unable to find resource: 131
-[0222/112842.824:WARNING:resource_bundle.cc(929)] unable to find resource: 132
-[0222/112842.828:WARNING:resource_bundle.cc(929)] unable to find resource: 133
-[0222/112842.829:WARNING:resource_bundle.cc(929)] unable to find resource: 134
-[0222/112842.831:WARNING:resource_bundle.cc(929)] unable to find resource: 135
-[0222/112842.832:WARNING:resource_bundle.cc(929)] unable to find resource: 136
-[0222/112842.834:WARNING:resource_bundle.cc(929)] unable to find resource: 137
-[0222/112842.837:WARNING:resource_bundle.cc(929)] unable to find resource: 138
-[0222/112842.890:WARNING:resource_bundle.cc(929)] unable to find resource: 139
-[0222/112842.925:WARNING:resource_bundle.cc(929)] unable to find resource: 140
-[0222/112842.977:WARNING:resource_bundle.cc(929)] unable to find resource: 141
-[0222/112842.999:WARNING:resource_bundle.cc(929)] unable to find resource: 142
-[0222/112843.055:WARNING:resource_bundle.cc(929)] unable to find resource: 143
-[0222/112843.059:WARNING:resource_bundle.cc(929)] unable to find resource: 144
-[0222/112843.060:WARNING:resource_bundle.cc(929)] unable to find resource: 145
-[0222/112843.068:WARNING:resource_bundle.cc(929)] unable to find resource: 146
-[0222/112843.071:WARNING:resource_bundle.cc(929)] unable to find resource: 147
-[0222/112843.073:WARNING:resource_bundle.cc(929)] unable to find resource: 148
-[0222/112843.074:WARNING:resource_bundle.cc(929)] unable to find resource: 149
-[0222/112843.075:WARNING:resource_bundle.cc(929)] unable to find resource: 150
-[0222/112843.077:WARNING:resource_bundle.cc(929)] unable to find resource: 151
-[0222/112843.078:WARNING:resource_bundle.cc(929)] unable to find resource: 152
-[0222/112843.079:WARNING:resource_bundle.cc(929)] unable to find resource: 153
-[0222/112843.081:WARNING:resource_bundle.cc(929)] unable to find resource: 154
-[0222/112843.082:WARNING:resource_bundle.cc(929)] unable to find resource: 155
-[0222/112843.083:WARNING:resource_bundle.cc(929)] unable to find resource: 156
-[0222/112843.085:WARNING:resource_bundle.cc(929)] unable to find resource: 157
-[0222/112843.089:WARNING:resource_bundle.cc(929)] unable to find resource: 158
-[0222/112843.095:WARNING:resource_bundle.cc(929)] unable to find resource: 159
-[0222/112843.102:WARNING:resource_bundle.cc(929)] unable to find resource: 160
-[0222/112843.105:WARNING:resource_bundle.cc(929)] unable to find resource: 161
-[0222/112843.108:WARNING:resource_bundle.cc(929)] unable to find resource: 162
-[0222/112843.519:WARNING:resource_bundle.cc(929)] unable to find resource: 289
-[0222/112843.522:WARNING:resource_bundle.cc(929)] unable to find resource: 290
-[0222/112847.917:WARNING:resource_bundle.cc(929)] unable to find resource: 194
-[0222/112847.918:WARNING:resource_bundle.cc(929)] unable to find resource: 195
-[0222/112858.177:INFO:CONSOLE(0)] "Mixed Content: The page at 'https://www.google.com/search?q=whats+up' was loaded over HTTPS, but requested an insecure image 'http://web.archive.org/web/*/https://id.google.com/verify/AAp5M_tuhTz-2PyMEHy0nYR2F3oJO7MxsZ64KQC0QfNyVVSBe1_jRWcXZC5dzuzbv1Y8_12vllwg7mZ4wgZmNe8IkC2vQiMGszS86x2QObmRkBAhER1wzJI'. This content should also be served over HTTPS.", source: https://www.google.com/search?q=whats+up (0)
-[0222/112905.673:INFO:CONSOLE(0)] "Mixed Content: The page at 'https://www.google.com/search?q=hello' was loaded over HTTPS, but requested an insecure image 'http://web.archive.org/web/*/https://id.google.com/verify/AAp5M_vnB38G1kwkhr1Jbxj-4Dc-i_hNBXAn_bqfYZCNFQ1AooBQ9JAOg79G5WmwZDyHuMmpfiqf6_bTT7LjFIBxlvPpbtHcCIESCrNwez6MzvfIByXTecw'. This content should also be served over HTTPS.", source: https://www.google.com/search?q=hello (0)
-[0222/112934.391:WARNING:resource_bundle.cc(929)] unable to find resource: 163
-[0222/112934.401:WARNING:resource_bundle.cc(929)] unable to find resource: 120
-[0222/112934.403:WARNING:resource_bundle.cc(929)] unable to find resource: 121
-[0222/112934.405:WARNING:resource_bundle.cc(929)] unable to find resource: 122
-[0222/112934.409:WARNING:resource_bundle.cc(929)] unable to find resource: 123
-[0222/112934.413:WARNING:resource_bundle.cc(929)] unable to find resource: 123
-[0222/112934.415:WARNING:resource_bundle.cc(929)] unable to find resource: 125
-[0222/112934.416:WARNING:resource_bundle.cc(929)] unable to find resource: 126
-[0222/112934.419:WARNING:resource_bundle.cc(929)] unable to find resource: 127
-[0222/112934.436:WARNING:resource_bundle.cc(929)] unable to find resource: 128
-[0222/112934.465:WARNING:resource_bundle.cc(929)] unable to find resource: 129
-[0222/112934.466:WARNING:resource_bundle.cc(929)] unable to find resource: 130
-[0222/112934.474:WARNING:resource_bundle.cc(929)] unable to find resource: 131
-[0222/112934.478:WARNING:resource_bundle.cc(929)] unable to find resource: 132
-[0222/112934.481:WARNING:resource_bundle.cc(929)] unable to find resource: 133
-[0222/112934.488:WARNING:resource_bundle.cc(929)] unable to find resource: 134
-[0222/112934.493:WARNING:resource_bundle.cc(929)] unable to find resource: 135
-[0222/112934.496:WARNING:resource_bundle.cc(929)] unable to find resource: 136
-[0222/112934.498:WARNING:resource_bundle.cc(929)] unable to find resource: 137
-[0222/112934.499:WARNING:resource_bundle.cc(929)] unable to find resource: 138
-[0222/112934.504:WARNING:resource_bundle.cc(929)] unable to find resource: 139
-[0222/112934.510:WARNING:resource_bundle.cc(929)] unable to find resource: 140
-[0222/112934.511:WARNING:resource_bundle.cc(929)] unable to find resource: 141
-[0222/112934.513:WARNING:resource_bundle.cc(929)] unable to find resource: 142
-[0222/112934.514:WARNING:resource_bundle.cc(929)] unable to find resource: 143
-[0222/112934.515:WARNING:resource_bundle.cc(929)] unable to find resource: 144
-[0222/112934.516:WARNING:resource_bundle.cc(929)] unable to find resource: 145
-[0222/112934.517:WARNING:resource_bundle.cc(929)] unable to find resource: 146
-[0222/112934.518:WARNING:resource_bundle.cc(929)] unable to find resource: 147
-[0222/112934.545:WARNING:resource_bundle.cc(929)] unable to find resource: 148
-[0222/112934.549:WARNING:resource_bundle.cc(929)] unable to find resource: 149
-[0222/112934.550:WARNING:resource_bundle.cc(929)] unable to find resource: 150
-[0222/112934.552:WARNING:resource_bundle.cc(929)] unable to find resource: 151
-[0222/112934.554:WARNING:resource_bundle.cc(929)] unable to find resource: 152
-[0222/112934.556:WARNING:resource_bundle.cc(929)] unable to find resource: 153
-[0222/112934.559:WARNING:resource_bundle.cc(929)] unable to find resource: 154
-[0222/112934.560:WARNING:resource_bundle.cc(929)] unable to find resource: 155
-[0222/112934.564:WARNING:resource_bundle.cc(929)] unable to find resource: 156
-[0222/112934.570:WARNING:resource_bundle.cc(929)] unable to find resource: 157
-[0222/112934.574:WARNING:resource_bundle.cc(929)] unable to find resource: 158
-[0222/112934.579:WARNING:resource_bundle.cc(929)] unable to find resource: 159
-[0222/112934.584:WARNING:resource_bundle.cc(929)] unable to find resource: 160
-[0222/112934.587:WARNING:resource_bundle.cc(929)] unable to find resource: 161
-[0222/112934.589:WARNING:resource_bundle.cc(929)] unable to find resource: 162
-[0222/112935.281:WARNING:resource_bundle.cc(929)] unable to find resource: 289
-[0222/112935.291:WARNING:resource_bundle.cc(929)] unable to find resource: 290
-[0222/112945.841:ERROR:broker_win.cc(137)] Error sending sync broker message: The pipe is being closed. (0xE8)
-[0222/112956.122:WARNING:resource_bundle.cc(929)] unable to find resource: 163
-[0222/112956.136:WARNING:resource_bundle.cc(929)] unable to find resource: 120
-[0222/112956.139:WARNING:resource_bundle.cc(929)] unable to find resource: 121
-[0222/112956.152:WARNING:resource_bundle.cc(929)] unable to find resource: 122
-[0222/112956.163:WARNING:resource_bundle.cc(929)] unable to find resource: 123
-[0222/112956.175:WARNING:resource_bundle.cc(929)] unable to find resource: 123
-[0222/112956.181:WARNING:resource_bundle.cc(929)] unable to find resource: 125
-[0222/112956.201:WARNING:resource_bundle.cc(929)] unable to find resource: 126
-[0222/112956.204:WARNING:resource_bundle.cc(929)] unable to find resource: 127
-[0222/112956.206:WARNING:resource_bundle.cc(929)] unable to find resource: 128
-[0222/112956.208:WARNING:resource_bundle.cc(929)] unable to find resource: 129
-[0222/112956.212:WARNING:resource_bundle.cc(929)] unable to find resource: 130
-[0222/112956.214:WARNING:resource_bundle.cc(929)] unable to find resource: 131
-[0222/112956.217:WARNING:resource_bundle.cc(929)] unable to find resource: 132
-[0222/112956.221:WARNING:resource_bundle.cc(929)] unable to find resource: 133
-[0222/112956.224:WARNING:resource_bundle.cc(929)] unable to find resource: 134
-[0222/112956.231:WARNING:resource_bundle.cc(929)] unable to find resource: 135
-[0222/112956.238:WARNING:resource_bundle.cc(929)] unable to find resource: 136
-[0222/112956.245:WARNING:resource_bundle.cc(929)] unable to find resource: 137
-[0222/112956.247:WARNING:resource_bundle.cc(929)] unable to find resource: 138
-[0222/112956.258:WARNING:resource_bundle.cc(929)] unable to find resource: 139
-[0222/112956.268:WARNING:resource_bundle.cc(929)] unable to find resource: 140
-[0222/112956.273:WARNING:resource_bundle.cc(929)] unable to find resource: 141
-[0222/112956.277:WARNING:resource_bundle.cc(929)] unable to find resource: 142
-[0222/112956.299:WARNING:resource_bundle.cc(929)] unable to find resource: 143
-[0222/112956.328:WARNING:resource_bundle.cc(929)] unable to find resource: 144
-[0222/112956.357:WARNING:resource_bundle.cc(929)] unable to find resource: 145
-[0222/112956.451:WARNING:resource_bundle.cc(929)] unable to find resource: 146
-[0222/112956.485:WARNING:resource_bundle.cc(929)] unable to find resource: 147
-[0222/112956.492:WARNING:resource_bundle.cc(929)] unable to find resource: 148
-[0222/112956.497:WARNING:resource_bundle.cc(929)] unable to find resource: 149
-[0222/112956.520:WARNING:resource_bundle.cc(929)] unable to find resource: 150
-[0222/112956.561:WARNING:resource_bundle.cc(929)] unable to find resource: 151
-[0222/112956.580:WARNING:resource_bundle.cc(929)] unable to find resource: 152
-[0222/112956.605:WARNING:resource_bundle.cc(929)] unable to find resource: 153
-[0222/112956.611:WARNING:resource_bundle.cc(929)] unable to find resource: 154
-[0222/112956.613:WARNING:resource_bundle.cc(929)] unable to find resource: 155
-[0222/112956.616:WARNING:resource_bundle.cc(929)] unable to find resource: 156
-[0222/112956.622:WARNING:resource_bundle.cc(929)] unable to find resource: 157
-[0222/112956.639:WARNING:resource_bundle.cc(929)] unable to find resource: 158
-[0222/112956.644:WARNING:resource_bundle.cc(929)] unable to find resource: 159
-[0222/112956.647:WARNING:resource_bundle.cc(929)] unable to find resource: 160
-[0222/112956.651:WARNING:resource_bundle.cc(929)] unable to find resource: 161
-[0222/112956.653:WARNING:resource_bundle.cc(929)] unable to find resource: 162
-[0222/112957.278:WARNING:resource_bundle.cc(929)] unable to find resource: 289
-[0222/112957.301:WARNING:resource_bundle.cc(929)] unable to find resource: 290
-[0222/113003.655:WARNING:resource_bundle.cc(929)] unable to find resource: 289
-[0222/113003.656:WARNING:resource_bundle.cc(929)] unable to find resource: 290
-[0222/113010.484:INFO:CONSOLE(485)] "chrome.loadTimes() is deprecated, instead use standardized API: nextHopProtocol in Navigation Timing 2. https://www.chromestatus.com/features/5637885046816768.", source: https://www.google.com/maps (485)
-[0222/113010.527:INFO:CONSOLE(485)] "chrome.loadTimes() is deprecated, instead use standardized API: nextHopProtocol in Navigation Timing 2. https://www.chromestatus.com/features/5637885046816768.", source: https://www.google.com/maps (485)
-[0222/113010.534:INFO:CONSOLE(485)] "chrome.loadTimes() is deprecated, instead use standardized API: nextHopProtocol in Navigation Timing 2. https://www.chromestatus.com/features/5637885046816768.", source: https://www.google.com/maps (485)
-[0222/113010.534:INFO:CONSOLE(485)] "chrome.loadTimes() is deprecated, instead use standardized API: nextHopProtocol in Navigation Timing 2. https://www.chromestatus.com/features/5637885046816768.", source: https://www.google.com/maps (485)
-[0222/113014.939:WARNING:angle_platform_impl.cc(52)] compileToBinary(232):
-C:\fakepath(116,32-88): warning X3571: pow(f, e) will not work for negative f, use abs(f) or conditionally handle negative values if you expect them
-
-[0222/113014.954:WARNING:angle_platform_impl.cc(52)] compileToBinary(232):
-C:\fakepath(210,32-88): warning X3571: pow(f, e) will not work for negative f, use abs(f) or conditionally handle negative values if you expect them
-C:\fakepath(211,32-88): warning X3571: pow(f, e) will not work for negative f, use abs(f) or conditionally handle negative values if you expect them
-
-[0222/113045.231:WARNING:resource_bundle.cc(929)] unable to find resource: 289
-[0222/113045.255:WARNING:resource_bundle.cc(929)] unable to find resource: 290
-[0222/113046.107:WARNING:resource_bundle.cc(929)] unable to find resource: 289
-[0222/113046.111:WARNING:resource_bundle.cc(929)] unable to find resource: 290
-[0222/113051.464:WARNING:resource_bundle.cc(929)] unable to find resource: 289
-[0222/113051.472:WARNING:resource_bundle.cc(929)] unable to find resource: 290
-[0222/113056.321:WARNING:resource_bundle.cc(929)] unable to find resource: 4629
-[0222/113056.322:ERROR:content_client.cc(265)] No localized string available for id 4629
-[0222/113056.379:WARNING:resource_bundle.cc(929)] unable to find resource: 4630
-[0222/113056.379:ERROR:content_client.cc(265)] No localized string available for id 4630
-[0222/113056.380:WARNING:resource_bundle.cc(929)] unable to find resource: 4632
-[0222/113056.381:ERROR:content_client.cc(265)] No localized string available for id 4632
-[0222/113056.381:WARNING:resource_bundle.cc(929)] unable to find resource: 4633
-[0222/113056.381:ERROR:content_client.cc(265)] No localized string available for id 4633
-[0222/113056.659:WARNING:resource_bundle.cc(929)] unable to find resource: 194
-[0222/113056.660:WARNING:resource_bundle.cc(929)] unable to find resource: 195
-[0222/113058.514:WARNING:resource_bundle.cc(929)] unable to find resource: 289
-[0222/113058.516:WARNING:resource_bundle.cc(929)] unable to find resource: 290
-[0222/113100.443:INFO:CONSOLE(292)] "%c%s", source: /_/boq-play/_/js/k=boq-play.PlayStoreUi.en_US.14pmrw_9BpY.O/am=ACBQIIAQBQ/rt=j/d=1/excm=appdetailsview,_b,_tp/ed=1/dg=0/rs=AB1caFXAedOerPt8GMZptjFAbS2LIE9FJQ/m=_b,_tp (292)
-[0222/113100.466:INFO:CONSOLE(292)] "%c%s", source: /_/boq-play/_/js/k=boq-play.PlayStoreUi.en_US.14pmrw_9BpY.O/am=ACBQIIAQBQ/rt=j/d=1/excm=appdetailsview,_b,_tp/ed=1/dg=0/rs=AB1caFXAedOerPt8GMZptjFAbS2LIE9FJQ/m=_b,_tp (292)
-[0222/113111.026:WARNING:resource_bundle.cc(929)] unable to find resource: 289
-[0222/113111.031:WARNING:resource_bundle.cc(929)] unable to find resource: 290
-[0222/113112.229:INFO:CONSOLE(506)] "chrome.loadTimes() is deprecated, instead use standardized API: nextHopProtocol in Navigation Timing 2. https://www.chromestatus.com/features/5637885046816768.", source: https://www.google.com/maps?q=whats+up&biw=1364&bih=625&dpr=1&um=1&ie=UTF-8&sa=X&ved=0ahUKEwjLoIGN1c7gAhXFqY8KHQU_DeUQ_AUIDSgE (506)
-[0222/113112.232:INFO:CONSOLE(506)] "chrome.loadTimes() is deprecated, instead use standardized API: nextHopProtocol in Navigation Timing 2. https://www.chromestatus.com/features/5637885046816768.", source: https://www.google.com/maps?q=whats+up&biw=1364&bih=625&dpr=1&um=1&ie=UTF-8&sa=X&ved=0ahUKEwjLoIGN1c7gAhXFqY8KHQU_DeUQ_AUIDSgE (506)
-[0222/113112.235:INFO:CONSOLE(506)] "chrome.loadTimes() is deprecated, instead use standardized API: nextHopProtocol in Navigation Timing 2. https://www.chromestatus.com/features/5637885046816768.", source: https://www.google.com/maps?q=whats+up&biw=1364&bih=625&dpr=1&um=1&ie=UTF-8&sa=X&ved=0ahUKEwjLoIGN1c7gAhXFqY8KHQU_DeUQ_AUIDSgE (506)
-[0222/113112.236:INFO:CONSOLE(506)] "chrome.loadTimes() is deprecated, instead use standardized API: nextHopProtocol in Navigation Timing 2. https://www.chromestatus.com/features/5637885046816768.", source: https://www.google.com/maps?q=whats+up&biw=1364&bih=625&dpr=1&um=1&ie=UTF-8&sa=X&ved=0ahUKEwjLoIGN1c7gAhXFqY8KHQU_DeUQ_AUIDSgE (506)
-[0222/113115.553:WARNING:resource_bundle.cc(929)] unable to find resource: 289
-[0222/113115.553:WARNING:resource_bundle.cc(929)] unable to find resource: 290
-[0222/113124.508:WARNING:spdy_session.cc(3144)] Received HEADERS for invalid stream 7
-[0222/113135.797:INFO:CONSOLE(7)] "AT:", source: https://www.apple.com/metrics/target/scripts/1.0/at.js (7)
-[0222/113144.201:WARNING:resource_bundle.cc(929)] unable to find resource: 20318
-[0222/113144.203:ERROR:content_client.cc(265)] No localized string available for id 20318
-[0222/113144.203:WARNING:resource_bundle.cc(929)] unable to find resource: 20314
-[0222/113144.204:ERROR:content_client.cc(265)] No localized string available for id 20314
-[0222/113144.204:WARNING:resource_bundle.cc(929)] unable to find resource: 20320
-[0222/113144.204:ERROR:content_client.cc(265)] No localized string available for id 20320
-[0222/113144.204:WARNING:resource_bundle.cc(929)] unable to find resource: 20317
-[0222/113144.204:ERROR:content_client.cc(265)] No localized string available for id 20317
-[0222/113144.205:WARNING:resource_bundle.cc(929)] unable to find resource: 20313
-[0222/113144.205:ERROR:content_client.cc(265)] No localized string available for id 20313
-[0222/113144.205:WARNING:resource_bundle.cc(929)] unable to find resource: 20311
-[0222/113144.205:ERROR:content_client.cc(265)] No localized string available for id 20311
-[0222/113144.206:WARNING:resource_bundle.cc(929)] unable to find resource: 20321
-[0222/113144.206:ERROR:content_client.cc(265)] No localized string available for id 20321
-[0222/113144.241:WARNING:resource_bundle.cc(929)] unable to find resource: 20318
-[0222/113144.241:ERROR:content_client.cc(265)] No localized string available for id 20318
-[0222/113144.241:WARNING:resource_bundle.cc(929)] unable to find resource: 20317
-[0222/113144.241:ERROR:content_client.cc(265)] No localized string available for id 20317
-[0222/113144.242:WARNING:resource_bundle.cc(929)] unable to find resource: 20311
-[0222/113144.242:ERROR:content_client.cc(265)] No localized string available for id 20311
-[0222/113144.290:WARNING:resource_bundle.cc(929)] unable to find resource: 20318
-[0222/113144.290:ERROR:content_client.cc(265)] No localized string available for id 20318
-[0222/113144.290:WARNING:resource_bundle.cc(929)] unable to find resource: 20317
-[0222/113144.291:ERROR:content_client.cc(265)] No localized string available for id 20317
-[0222/113144.291:WARNING:resource_bundle.cc(929)] unable to find resource: 20311
-[0222/113144.291:ERROR:content_client.cc(265)] No localized string available for id 20311
-[0222/113144.292:WARNING:resource_bundle.cc(929)] unable to find resource: 20318
-[0222/113144.293:ERROR:content_client.cc(265)] No localized string available for id 20318
-[0222/113144.293:WARNING:resource_bundle.cc(929)] unable to find resource: 20314
-[0222/113144.293:ERROR:content_client.cc(265)] No localized string available for id 20314
-[0222/113144.293:WARNING:resource_bundle.cc(929)] unable to find resource: 20320
-[0222/113144.294:ERROR:content_client.cc(265)] No localized string available for id 20320
-[0222/113144.294:WARNING:resource_bundle.cc(929)] unable to find resource: 20317
-[0222/113144.294:ERROR:content_client.cc(265)] No localized string available for id 20317
-[0222/113144.294:WARNING:resource_bundle.cc(929)] unable to find resource: 20313
-[0222/113144.294:ERROR:content_client.cc(265)] No localized string available for id 20313
-[0222/113144.295:WARNING:resource_bundle.cc(929)] unable to find resource: 20311
-[0222/113144.295:ERROR:content_client.cc(265)] No localized string available for id 20311
-[0222/113144.295:WARNING:resource_bundle.cc(929)] unable to find resource: 20321
-[0222/113144.295:ERROR:content_client.cc(265)] No localized string available for id 20321
-[0222/113144.297:WARNING:resource_bundle.cc(929)] unable to find resource: 20318
-[0222/113144.297:ERROR:content_client.cc(265)] No localized string available for id 20318
-[0222/113144.297:WARNING:resource_bundle.cc(929)] unable to find resource: 20317
-[0222/113144.297:ERROR:content_client.cc(265)] No localized string available for id 20317
-[0222/113144.298:WARNING:resource_bundle.cc(929)] unable to find resource: 20311
-[0222/113144.298:ERROR:content_client.cc(265)] No localized string available for id 20311
-[0222/113144.298:WARNING:resource_bundle.cc(929)] unable to find resource: 20318
-[0222/113144.298:ERROR:content_client.cc(265)] No localized string available for id 20318
-[0222/113144.299:WARNING:resource_bundle.cc(929)] unable to find resource: 20317
-[0222/113144.299:ERROR:content_client.cc(265)] No localized string available for id 20317
-[0222/113144.299:WARNING:resource_bundle.cc(929)] unable to find resource: 20311
-[0222/113144.299:ERROR:content_client.cc(265)] No localized string available for id 20311
-[0222/113144.300:WARNING:resource_bundle.cc(929)] unable to find resource: 20318
-[0222/113144.301:ERROR:content_client.cc(265)] No localized string available for id 20318
-[0222/113144.301:WARNING:resource_bundle.cc(929)] unable to find resource: 20314
-[0222/113144.301:ERROR:content_client.cc(265)] No localized string available for id 20314
-[0222/113144.301:WARNING:resource_bundle.cc(929)] unable to find resource: 20320
-[0222/113144.301:ERROR:content_client.cc(265)] No localized string available for id 20320
-[0222/113144.302:WARNING:resource_bundle.cc(929)] unable to find resource: 20317
-[0222/113144.302:ERROR:content_client.cc(265)] No localized string available for id 20317
-[0222/113144.302:WARNING:resource_bundle.cc(929)] unable to find resource: 20313
-[0222/113144.302:ERROR:content_client.cc(265)] No localized string available for id 20313
-[0222/113144.303:WARNING:resource_bundle.cc(929)] unable to find resource: 20311
-[0222/113144.303:ERROR:content_client.cc(265)] No localized string available for id 20311
-[0222/113144.303:WARNING:resource_bundle.cc(929)] unable to find resource: 20321
-[0222/113144.303:ERROR:content_client.cc(265)] No localized string available for id 20321
-[0222/113144.303:WARNING:resource_bundle.cc(929)] unable to find resource: 20318
-[0222/113144.304:ERROR:content_client.cc(265)] No localized string available for id 20318
-[0222/113144.304:WARNING:resource_bundle.cc(929)] unable to find resource: 20317
-[0222/113144.304:ERROR:content_client.cc(265)] No localized string available for id 20317
-[0222/113144.304:WARNING:resource_bundle.cc(929)] unable to find resource: 20311
-[0222/113144.304:ERROR:content_client.cc(265)] No localized string available for id 20311
-[0222/113144.305:WARNING:resource_bundle.cc(929)] unable to find resource: 20318
-[0222/113144.305:ERROR:content_client.cc(265)] No localized string available for id 20318
-[0222/113144.305:WARNING:resource_bundle.cc(929)] unable to find resource: 20317
-[0222/113144.305:ERROR:content_client.cc(265)] No localized string available for id 20317
-[0222/113144.306:WARNING:resource_bundle.cc(929)] unable to find resource: 20311
-[0222/113144.306:ERROR:content_client.cc(265)] No localized string available for id 20311
-[0222/113144.307:WARNING:resource_bundle.cc(929)] unable to find resource: 20318
-[0222/113144.307:ERROR:content_client.cc(265)] No localized string available for id 20318
-[0222/113144.308:WARNING:resource_bundle.cc(929)] unable to find resource: 20314
-[0222/113144.308:ERROR:content_client.cc(265)] No localized string available for id 20314
-[0222/113144.308:WARNING:resource_bundle.cc(929)] unable to find resource: 20320
-[0222/113144.308:ERROR:content_client.cc(265)] No localized string available for id 20320
-[0222/113144.308:WARNING:resource_bundle.cc(929)] unable to find resource: 20317
-[0222/113144.309:ERROR:content_client.cc(265)] No localized string available for id 20317
-[0222/113144.309:WARNING:resource_bundle.cc(929)] unable to find resource: 20313
-[0222/113144.309:ERROR:content_client.cc(265)] No localized string available for id 20313
-[0222/113144.309:WARNING:resource_bundle.cc(929)] unable to find resource: 20311
-[0222/113144.309:ERROR:content_client.cc(265)] No localized string available for id 20311
-[0222/113144.310:WARNING:resource_bundle.cc(929)] unable to find resource: 20321
-[0222/113144.310:ERROR:content_client.cc(265)] No localized string available for id 20321
-[0222/113144.310:WARNING:resource_bundle.cc(929)] unable to find resource: 20318
-[0222/113144.310:ERROR:content_client.cc(265)] No localized string available for id 20318
-[0222/113144.311:WARNING:resource_bundle.cc(929)] unable to find resource: 20317
-[0222/113144.311:ERROR:content_client.cc(265)] No localized string available for id 20317
-[0222/113144.311:WARNING:resource_bundle.cc(929)] unable to find resource: 20311
-[0222/113144.311:ERROR:content_client.cc(265)] No localized string available for id 20311
-[0222/113144.312:WARNING:resource_bundle.cc(929)] unable to find resource: 20318
-[0222/113144.312:ERROR:content_client.cc(265)] No localized string available for id 20318
-[0222/113144.312:WARNING:resource_bundle.cc(929)] unable to find resource: 20317
-[0222/113144.312:ERROR:content_client.cc(265)] No localized string available for id 20317
-[0222/113144.314:WARNING:resource_bundle.cc(929)] unable to find resource: 20311
-[0222/113144.314:ERROR:content_client.cc(265)] No localized string available for id 20311
-[0222/113144.315:WARNING:resource_bundle.cc(929)] unable to find resource: 20318
-[0222/113144.315:ERROR:content_client.cc(265)] No localized string available for id 20318
-[0222/113144.316:WARNING:resource_bundle.cc(929)] unable to find resource: 20314
-[0222/113144.316:ERROR:content_client.cc(265)] No localized string available for id 20314
-[0222/113144.316:WARNING:resource_bundle.cc(929)] unable to find resource: 20320
-[0222/113144.316:ERROR:content_client.cc(265)] No localized string available for id 20320
-[0222/113144.317:WARNING:resource_bundle.cc(929)] unable to find resource: 20317
-[0222/113144.317:ERROR:content_client.cc(265)] No localized string available for id 20317
-[0222/113144.317:WARNING:resource_bundle.cc(929)] unable to find resource: 20313
-[0222/113144.318:ERROR:content_client.cc(265)] No localized string available for id 20313
-[0222/113144.318:WARNING:resource_bundle.cc(929)] unable to find resource: 20311
-[0222/113144.318:ERROR:content_client.cc(265)] No localized string available for id 20311
-[0222/113144.319:WARNING:resource_bundle.cc(929)] unable to find resource: 20321
-[0222/113144.319:ERROR:content_client.cc(265)] No localized string available for id 20321
-[0222/113144.319:WARNING:resource_bundle.cc(929)] unable to find resource: 20318
-[0222/113144.320:ERROR:content_client.cc(265)] No localized string available for id 20318
-[0222/113144.320:WARNING:resource_bundle.cc(929)] unable to find resource: 20317
-[0222/113144.320:ERROR:content_client.cc(265)] No localized string available for id 20317
-[0222/113144.320:WARNING:resource_bundle.cc(929)] unable to find resource: 20311
-[0222/113144.321:ERROR:content_client.cc(265)] No localized string available for id 20311
-[0222/113144.321:WARNING:resource_bundle.cc(929)] unable to find resource: 20318
-[0222/113144.322:ERROR:content_client.cc(265)] No localized string available for id 20318
-[0222/113144.322:WARNING:resource_bundle.cc(929)] unable to find resource: 20317
-[0222/113144.322:ERROR:content_client.cc(265)] No localized string available for id 20317
-[0222/113144.322:WARNING:resource_bundle.cc(929)] unable to find resource: 20311
-[0222/113144.323:ERROR:content_client.cc(265)] No localized string available for id 20311
-[0222/113144.324:WARNING:resource_bundle.cc(929)] unable to find resource: 20318
-[0222/113144.324:ERROR:content_client.cc(265)] No localized string available for id 20318
-[0222/113144.325:WARNING:resource_bundle.cc(929)] unable to find resource: 20314
-[0222/113144.325:ERROR:content_client.cc(265)] No localized string available for id 20314
-[0222/113144.325:WARNING:resource_bundle.cc(929)] unable to find resource: 20320
-[0222/113144.326:ERROR:content_client.cc(265)] No localized string available for id 20320
-[0222/113144.326:WARNING:resource_bundle.cc(929)] unable to find resource: 20317
-[0222/113144.326:ERROR:content_client.cc(265)] No localized string available for id 20317
-[0222/113144.327:WARNING:resource_bundle.cc(929)] unable to find resource: 20313
-[0222/113144.327:ERROR:content_client.cc(265)] No localized string available for id 20313
-[0222/113144.328:WARNING:resource_bundle.cc(929)] unable to find resource: 20311
-[0222/113144.328:ERROR:content_client.cc(265)] No localized string available for id 20311
-[0222/113144.328:WARNING:resource_bundle.cc(929)] unable to find resource: 20321
-[0222/113144.328:ERROR:content_client.cc(265)] No localized string available for id 20321
-[0222/113144.329:WARNING:resource_bundle.cc(929)] unable to find resource: 20318
-[0222/113144.329:ERROR:content_client.cc(265)] No localized string available for id 20318
-[0222/113144.329:WARNING:resource_bundle.cc(929)] unable to find resource: 20317
-[0222/113144.330:ERROR:content_client.cc(265)] No localized string available for id 20317
-[0222/113144.330:WARNING:resource_bundle.cc(929)] unable to find resource: 20311
-[0222/113144.330:ERROR:content_client.cc(265)] No localized string available for id 20311
-[0222/113144.331:WARNING:resource_bundle.cc(929)] unable to find resource: 20318
-[0222/113144.331:ERROR:content_client.cc(265)] No localized string available for id 20318
-[0222/113144.331:WARNING:resource_bundle.cc(929)] unable to find resource: 20317
-[0222/113144.331:ERROR:content_client.cc(265)] No localized string available for id 20317
-[0222/113144.332:WARNING:resource_bundle.cc(929)] unable to find resource: 20311
-[0222/113144.332:ERROR:content_client.cc(265)] No localized string available for id 20311
-[0222/113144.334:WARNING:resource_bundle.cc(929)] unable to find resource: 20318
-[0222/113144.335:ERROR:content_client.cc(265)] No localized string available for id 20318
-[0222/113144.335:WARNING:resource_bundle.cc(929)] unable to find resource: 20314
-[0222/113144.335:ERROR:content_client.cc(265)] No localized string available for id 20314
-[0222/113144.336:WARNING:resource_bundle.cc(929)] unable to find resource: 20320
-[0222/113144.336:ERROR:content_client.cc(265)] No localized string available for id 20320
-[0222/113144.336:WARNING:resource_bundle.cc(929)] unable to find resource: 20317
-[0222/113144.337:ERROR:content_client.cc(265)] No localized string available for id 20317
-[0222/113144.337:WARNING:resource_bundle.cc(929)] unable to find resource: 20313
-[0222/113144.337:ERROR:content_client.cc(265)] No localized string available for id 20313
-[0222/113144.338:WARNING:resource_bundle.cc(929)] unable to find resource: 20311
-[0222/113144.338:ERROR:content_client.cc(265)] No localized string available for id 20311
-[0222/113144.338:WARNING:resource_bundle.cc(929)] unable to find resource: 20321
-[0222/113144.339:ERROR:content_client.cc(265)] No localized string available for id 20321
-[0222/113144.339:WARNING:resource_bundle.cc(929)] unable to find resource: 20318
-[0222/113144.339:ERROR:content_client.cc(265)] No localized string available for id 20318
-[0222/113144.340:WARNING:resource_bundle.cc(929)] unable to find resource: 20317
-[0222/113144.340:ERROR:content_client.cc(265)] No localized string available for id 20317
-[0222/113144.341:WARNING:resource_bundle.cc(929)] unable to find resource: 20311
-[0222/113144.341:ERROR:content_client.cc(265)] No localized string available for id 20311
-[0222/113144.342:WARNING:resource_bundle.cc(929)] unable to find resource: 20318
-[0222/113144.342:ERROR:content_client.cc(265)] No localized string available for id 20318
-[0222/113144.343:WARNING:resource_bundle.cc(929)] unable to find resource: 20317
-[0222/113144.343:ERROR:content_client.cc(265)] No localized string available for id 20317
-[0222/113144.343:WARNING:resource_bundle.cc(929)] unable to find resource: 20311
-[0222/113144.343:ERROR:content_client.cc(265)] No localized string available for id 20311
-[0222/113144.345:WARNING:resource_bundle.cc(929)] unable to find resource: 20318
-[0222/113144.346:ERROR:content_client.cc(265)] No localized string available for id 20318
-[0222/113144.346:WARNING:resource_bundle.cc(929)] unable to find resource: 20314
-[0222/113144.346:ERROR:content_client.cc(265)] No localized string available for id 20314
-[0222/113144.347:WARNING:resource_bundle.cc(929)] unable to find resource: 20320
-[0222/113144.347:ERROR:content_client.cc(265)] No localized string available for id 20320
-[0222/113144.347:WARNING:resource_bundle.cc(929)] unable to find resource: 20317
-[0222/113144.348:ERROR:content_client.cc(265)] No localized string available for id 20317
-[0222/113144.348:WARNING:resource_bundle.cc(929)] unable to find resource: 20313
-[0222/113144.348:ERROR:content_client.cc(265)] No localized string available for id 20313
-[0222/113144.349:WARNING:resource_bundle.cc(929)] unable to find resource: 20311
-[0222/113144.349:ERROR:content_client.cc(265)] No localized string available for id 20311
-[0222/113144.349:WARNING:resource_bundle.cc(929)] unable to find resource: 20321
-[0222/113144.349:ERROR:content_client.cc(265)] No localized string available for id 20321
-[0222/113144.350:WARNING:resource_bundle.cc(929)] unable to find resource: 20318
-[0222/113144.350:ERROR:content_client.cc(265)] No localized string available for id 20318
-[0222/113144.351:WARNING:resource_bundle.cc(929)] unable to find resource: 20317
-[0222/113144.351:ERROR:content_client.cc(265)] No localized string available for id 20317
-[0222/113144.351:WARNING:resource_bundle.cc(929)] unable to find resource: 20311
-[0222/113144.351:ERROR:content_client.cc(265)] No localized string available for id 20311
-[0222/113144.352:WARNING:resource_bundle.cc(929)] unable to find resource: 20318
-[0222/113144.352:ERROR:content_client.cc(265)] No localized string available for id 20318
-[0222/113144.353:WARNING:resource_bundle.cc(929)] unable to find resource: 20317
-[0222/113144.353:ERROR:content_client.cc(265)] No localized string available for id 20317
-[0222/113144.353:WARNING:resource_bundle.cc(929)] unable to find resource: 20311
-[0222/113144.353:ERROR:content_client.cc(265)] No localized string available for id 20311
-[0222/113144.354:WARNING:resource_bundle.cc(929)] unable to find resource: 20318
-[0222/113144.355:ERROR:content_client.cc(265)] No localized string available for id 20318
-[0222/113144.355:WARNING:resource_bundle.cc(929)] unable to find resource: 20314
-[0222/113144.355:ERROR:content_client.cc(265)] No localized string available for id 20314
-[0222/113144.356:WARNING:resource_bundle.cc(929)] unable to find resource: 20320
-[0222/113144.356:ERROR:content_client.cc(265)] No localized string available for id 20320
-[0222/113144.356:WARNING:resource_bundle.cc(929)] unable to find resource: 20317
-[0222/113144.357:ERROR:content_client.cc(265)] No localized string available for id 20317
-[0222/113144.359:WARNING:resource_bundle.cc(929)] unable to find resource: 20313
-[0222/113144.359:ERROR:content_client.cc(265)] No localized string available for id 20313
-[0222/113144.359:WARNING:resource_bundle.cc(929)] unable to find resource: 20311
-[0222/113144.359:ERROR:content_client.cc(265)] No localized string available for id 20311
-[0222/113144.360:WARNING:resource_bundle.cc(929)] unable to find resource: 20321
-[0222/113144.360:ERROR:content_client.cc(265)] No localized string available for id 20321
-[0222/113144.360:WARNING:resource_bundle.cc(929)] unable to find resource: 20318
-[0222/113144.360:ERROR:content_client.cc(265)] No localized string available for id 20318
-[0222/113144.361:WARNING:resource_bundle.cc(929)] unable to find resource: 20317
-[0222/113144.361:ERROR:content_client.cc(265)] No localized string available for id 20317
-[0222/113144.361:WARNING:resource_bundle.cc(929)] unable to find resource: 20311
-[0222/113144.361:ERROR:content_client.cc(265)] No localized string available for id 20311
-[0222/113144.362:WARNING:resource_bundle.cc(929)] unable to find resource: 20318
-[0222/113144.362:ERROR:content_client.cc(265)] No localized string available for id 20318
-[0222/113144.362:WARNING:resource_bundle.cc(929)] unable to find resource: 20317
-[0222/113144.363:ERROR:content_client.cc(265)] No localized string available for id 20317
-[0222/113144.363:WARNING:resource_bundle.cc(929)] unable to find resource: 20311
-[0222/113144.363:ERROR:content_client.cc(265)] No localized string available for id 20311
-[0222/113144.364:WARNING:resource_bundle.cc(929)] unable to find resource: 20318
-[0222/113144.365:ERROR:content_client.cc(265)] No localized string available for id 20318
-[0222/113144.365:WARNING:resource_bundle.cc(929)] unable to find resource: 20314
-[0222/113144.365:ERROR:content_client.cc(265)] No localized string available for id 20314
-[0222/113144.365:WARNING:resource_bundle.cc(929)] unable to find resource: 20320
-[0222/113144.366:ERROR:content_client.cc(265)] No localized string available for id 20320
-[0222/113144.366:WARNING:resource_bundle.cc(929)] unable to find resource: 20317
-[0222/113144.366:ERROR:content_client.cc(265)] No localized string available for id 20317
-[0222/113144.366:WARNING:resource_bundle.cc(929)] unable to find resource: 20313
-[0222/113144.366:ERROR:content_client.cc(265)] No localized string available for id 20313
-[0222/113144.367:WARNING:resource_bundle.cc(929)] unable to find resource: 20311
-[0222/113144.367:ERROR:content_client.cc(265)] No localized string available for id 20311
-[0222/113144.368:WARNING:resource_bundle.cc(929)] unable to find resource: 20321
-[0222/113144.368:ERROR:content_client.cc(265)] No localized string available for id 20321
-[0222/113144.368:WARNING:resource_bundle.cc(929)] unable to find resource: 20318
-[0222/113144.368:ERROR:content_client.cc(265)] No localized string available for id 20318
-[0222/113144.369:WARNING:resource_bundle.cc(929)] unable to find resource: 20317
-[0222/113144.369:ERROR:content_client.cc(265)] No localized string available for id 20317
-[0222/113144.369:WARNING:resource_bundle.cc(929)] unable to find resource: 20311
-[0222/113144.369:ERROR:content_client.cc(265)] No localized string available for id 20311
-[0222/113144.370:WARNING:resource_bundle.cc(929)] unable to find resource: 20318
-[0222/113144.370:ERROR:content_client.cc(265)] No localized string available for id 20318
-[0222/113144.370:WARNING:resource_bundle.cc(929)] unable to find resource: 20317
-[0222/113144.370:ERROR:content_client.cc(265)] No localized string available for id 20317
-[0222/113144.371:WARNING:resource_bundle.cc(929)] unable to find resource: 20311
-[0222/113144.371:ERROR:content_client.cc(265)] No localized string available for id 20311
-[0222/113144.928:INFO:CONSOLE(1)] "Uncaught TypeError: Cannot read property 'filter' of undefined", source: https://www.apple.com/metrics/ac-analytics/2.6.0/scripts/ac-analytics.js (1)
-[0222/113144.935:INFO:CONSOLE(1)] "Uncaught TypeError: Cannot read property 'filter' of undefined", source: https://www.apple.com/metrics/ac-analytics/2.6.0/scripts/ac-analytics.js (1)
-[0222/113214.061:WARNING:resource_bundle.cc(929)] unable to find resource: 289
-[0222/113214.065:WARNING:resource_bundle.cc(929)] unable to find resource: 290
-[0222/113217.067:ERROR:ssl_client_socket_impl.cc(1013)] handshake failed; returned -1, SSL error code 1, net_error -101
-[0222/113223.241:WARNING:resource_bundle.cc(929)] unable to find resource: 289
-[0222/113223.241:WARNING:resource_bundle.cc(929)] unable to find resource: 290
-[0222/113243.059:WARNING:resource_bundle.cc(929)] unable to find resource: 289
-[0222/113243.063:WARNING:resource_bundle.cc(929)] unable to find resource: 290
-[0222/113244.463:WARNING:CONSOLE(3124)] "document.registerElement is deprecated and will be removed in M73, around March 2019. Please use window.customElements.define instead. See https://www.chromestatus.com/features/4642138092470272 for more details.", source: chrome-devtools://devtools/shell.js (3124)
-[0222/113244.691:WARNING:CONSOLE(3082)] "Element.createShadowRoot is deprecated and will be removed in M73, around March 2019. Please use Element.attachShadow instead. See https://www.chromestatus.com/features/4507242028072960 for more details.", source: chrome-devtools://devtools/shell.js (3082)
-[0222/113400.980:WARNING:resource_bundle.cc(929)] unable to find resource: 289
-[0222/113401.026:WARNING:resource_bundle.cc(929)] unable to find resource: 290
-[0222/113534.120:WARNING:resource_bundle.cc(929)] unable to find resource: 163
-[0222/113534.249:WARNING:resource_bundle.cc(929)] unable to find resource: 120
-[0222/113534.304:WARNING:resource_bundle.cc(929)] unable to find resource: 121
-[0222/113534.350:WARNING:resource_bundle.cc(929)] unable to find resource: 122
-[0222/113534.359:WARNING:resource_bundle.cc(929)] unable to find resource: 123
-[0222/113534.371:WARNING:resource_bundle.cc(929)] unable to find resource: 123
-[0222/113534.388:WARNING:resource_bundle.cc(929)] unable to find resource: 125
-[0222/113534.409:WARNING:resource_bundle.cc(929)] unable to find resource: 126
-[0222/113534.429:WARNING:resource_bundle.cc(929)] unable to find resource: 127
-[0222/113534.443:WARNING:resource_bundle.cc(929)] unable to find resource: 128
-[0222/113534.461:WARNING:resource_bundle.cc(929)] unable to find resource: 129
-[0222/113534.493:WARNING:resource_bundle.cc(929)] unable to find resource: 130
-[0222/113534.514:WARNING:resource_bundle.cc(929)] unable to find resource: 131
-[0222/113534.522:WARNING:resource_bundle.cc(929)] unable to find resource: 132
-[0222/113534.529:WARNING:resource_bundle.cc(929)] unable to find resource: 133
-[0222/113534.531:WARNING:resource_bundle.cc(929)] unable to find resource: 134
-[0222/113534.532:WARNING:resource_bundle.cc(929)] unable to find resource: 135
-[0222/113534.533:WARNING:resource_bundle.cc(929)] unable to find resource: 136
-[0222/113534.534:WARNING:resource_bundle.cc(929)] unable to find resource: 137
-[0222/113534.535:WARNING:resource_bundle.cc(929)] unable to find resource: 138
-[0222/113534.536:WARNING:resource_bundle.cc(929)] unable to find resource: 139
-[0222/113534.537:WARNING:resource_bundle.cc(929)] unable to find resource: 140
-[0222/113534.538:WARNING:resource_bundle.cc(929)] unable to find resource: 141
-[0222/113534.547:WARNING:resource_bundle.cc(929)] unable to find resource: 142
-[0222/113534.555:WARNING:resource_bundle.cc(929)] unable to find resource: 143
-[0222/113534.557:WARNING:resource_bundle.cc(929)] unable to find resource: 144
-[0222/113534.559:WARNING:resource_bundle.cc(929)] unable to find resource: 145
-[0222/113534.561:WARNING:resource_bundle.cc(929)] unable to find resource: 146
-[0222/113534.562:WARNING:resource_bundle.cc(929)] unable to find resource: 147
-[0222/113534.564:WARNING:resource_bundle.cc(929)] unable to find resource: 148
-[0222/113534.566:WARNING:resource_bundle.cc(929)] unable to find resource: 149
-[0222/113534.569:WARNING:resource_bundle.cc(929)] unable to find resource: 150
-[0222/113534.570:WARNING:resource_bundle.cc(929)] unable to find resource: 151
-[0222/113534.573:WARNING:resource_bundle.cc(929)] unable to find resource: 152
-[0222/113534.589:WARNING:resource_bundle.cc(929)] unable to find resource: 153
-[0222/113534.595:WARNING:resource_bundle.cc(929)] unable to find resource: 154
-[0222/113534.610:WARNING:resource_bundle.cc(929)] unable to find resource: 155
-[0222/113534.611:WARNING:resource_bundle.cc(929)] unable to find resource: 156
-[0222/113534.612:WARNING:resource_bundle.cc(929)] unable to find resource: 157
-[0222/113534.613:WARNING:resource_bundle.cc(929)] unable to find resource: 158
-[0222/113534.624:WARNING:resource_bundle.cc(929)] unable to find resource: 159
-[0222/113534.628:WARNING:resource_bundle.cc(929)] unable to find resource: 160
-[0222/113534.631:WARNING:resource_bundle.cc(929)] unable to find resource: 161
-[0222/113534.633:WARNING:resource_bundle.cc(929)] unable to find resource: 162
-[0222/113536.128:WARNING:resource_bundle.cc(929)] unable to find resource: 289
-[0222/113536.131:WARNING:resource_bundle.cc(929)] unable to find resource: 290
-[0222/113543.310:WARNING:resource_bundle.cc(929)] unable to find resource: 194
-[0222/113543.310:WARNING:resource_bundle.cc(929)] unable to find resource: 195
-[0222/113546.240:INFO:CONSOLE(299)] "%c%s", source: https://www.gstatic.com/_/mss/boq-identity/_/js/k=boq-identity.AccountSettingsUi.en_US.ESWhUWvzKSQ.O/am=_qAC4vx86hEAGQgIAAAAAAAgCA/rt=j/d=1/excm=welcomeintroview,_b,_tp/ed=1/dg=0/rs=AOaEmlFMkL4aHCw2h11Z5vu6aVUW4SWR0Q/m=_b,_tp (299)
-[0222/113546.243:INFO:CONSOLE(299)] "%c%s", source: https://www.gstatic.com/_/mss/boq-identity/_/js/k=boq-identity.AccountSettingsUi.en_US.ESWhUWvzKSQ.O/am=_qAC4vx86hEAGQgIAAAAAAAgCA/rt=j/d=1/excm=welcomeintroview,_b,_tp/ed=1/dg=0/rs=AOaEmlFMkL4aHCw2h11Z5vu6aVUW4SWR0Q/m=_b,_tp (299)
-[0222/113552.117:WARNING:resource_bundle.cc(929)] unable to find resource: 4629
-[0222/113552.118:ERROR:content_client.cc(265)] No localized string available for id 4629
-[0222/113552.119:WARNING:resource_bundle.cc(929)] unable to find resource: 4630
-[0222/113552.121:ERROR:content_client.cc(265)] No localized string available for id 4630
-[0222/113552.121:WARNING:resource_bundle.cc(929)] unable to find resource: 4632
-[0222/113552.122:ERROR:content_client.cc(265)] No localized string available for id 4632
-[0222/113552.123:WARNING:resource_bundle.cc(929)] unable to find resource: 4633
-[0222/113552.124:ERROR:content_client.cc(265)] No localized string available for id 4633
-[0222/113552.144:WARNING:resource_bundle.cc(929)] unable to find resource: 194
-[0222/113552.144:WARNING:resource_bundle.cc(929)] unable to find resource: 195
-[0222/113553.673:WARNING:resource_bundle.cc(929)] unable to find resource: 289
-[0222/113553.679:WARNING:resource_bundle.cc(929)] unable to find resource: 290
-[0222/113554.192:WARNING:CONSOLE(3124)] "document.registerElement is deprecated and will be removed in M73, around March 2019. Please use window.customElements.define instead. See https://www.chromestatus.com/features/4642138092470272 for more details.", source: chrome-devtools://devtools/shell.js (3124)
-[0222/113554.272:WARNING:CONSOLE(3082)] "Element.createShadowRoot is deprecated and will be removed in M73, around March 2019. Please use Element.attachShadow instead. See https://www.chromestatus.com/features/4507242028072960 for more details.", source: chrome-devtools://devtools/shell.js (3082)
-[0222/113640.423:WARNING:resource_bundle.cc(929)] unable to find resource: 4629
-[0222/113640.425:ERROR:content_client.cc(265)] No localized string available for id 4629
-[0222/113640.429:WARNING:resource_bundle.cc(929)] unable to find resource: 4630
-[0222/113640.431:ERROR:content_client.cc(265)] No localized string available for id 4630
-[0222/113640.434:WARNING:resource_bundle.cc(929)] unable to find resource: 4632
-[0222/113640.435:ERROR:content_client.cc(265)] No localized string available for id 4632
-[0222/113640.437:WARNING:resource_bundle.cc(929)] unable to find resource: 4633
-[0222/113640.439:ERROR:content_client.cc(265)] No localized string available for id 4633
-[0222/113640.472:WARNING:resource_bundle.cc(929)] unable to find resource: 194
-[0222/113640.473:WARNING:resource_bundle.cc(929)] unable to find resource: 195
-[0222/113747.884:WARNING:resource_bundle.cc(929)] unable to find resource: 289
-[0222/113747.908:WARNING:resource_bundle.cc(929)] unable to find resource: 290
-[0222/113748.102:WARNING:resource_bundle.cc(929)] unable to find resource: 289
-[0222/113748.102:WARNING:resource_bundle.cc(929)] unable to find resource: 290
-[0222/113812.957:WARNING:resource_bundle.cc(929)] unable to find resource: 289
-[0222/113812.957:WARNING:resource_bundle.cc(929)] unable to find resource: 290
-[0222/113835.881:INFO:CONSOLE(1)] "Uncaught SyntaxError: Unexpected token <", source: sharpbrowser://storage/errors/notFound.html?path=F%3A%5Cjs%5Cjquery.min.js (1)
-[0222/113835.882:INFO:CONSOLE(1)] "Uncaught SyntaxError: Unexpected token <", source: sharpbrowser://storage/errors/notFound.html?path=F%3A%5Cjs%5Cbootstrap.min.js (1)
-[0222/113835.883:INFO:CONSOLE(1)] "Uncaught SyntaxError: Unexpected token <", source: sharpbrowser://storage/errors/notFound.html?path=F%3A%5Cjs%5Cclient.min.js (1)
-[0222/113835.883:INFO:CONSOLE(1)] "Uncaught SyntaxError: Unexpected token <", source: sharpbrowser://storage/errors/notFound.html?path=file%3A%5C%5Ccdn.jsdelivr.net%5Cnpm%5Cslick-carousel%401.8.1%5Cslick%5Cslick.min.js (1)
-[0222/113844.260:WARNING:resource_bundle.cc(929)] unable to find resource: 289
-[0222/113844.264:WARNING:resource_bundle.cc(929)] unable to find resource: 290
-[0222/114722.042:INFO:CONSOLE(145)] "JQMIGRATE: Migrate is installed with logging active, version 3.0.1", source: https://en.wiktionary.org/w/load.php?debug=false&lang=en&modules=Spinner%2Cjquery%2Coojs%2Coojs-ui-core%2Csite%7Cext.centralNotice.choiceData%2Cdisplay%2CgeoIP%2CimpressionDiet%2CkvStore%2CkvStoreMaintenance%2ClegacySupport%2CstartUp%7Cext.centralauth.centralautologin%7Cext.eventLogging%2CnavigationTiming%2CwikimediaEvents%7Cext.eventLogging.subscriber%7Cext.uls.common%2Ccompactlinks%2Ceventlogger%2Cinit%2Cinterface%2Cpreferences%2Cwebfonts%7Cext.visualEditor.desktopArticleTarget.init%7Cext.visualEditor.progressBarWidget%2CsupportCheck%2CtargetLoader%2CtempWikitextEditorWidget%2Ctrack%2Cve%7Cjquery.accessKeyLabel%2CcheckboxShiftClick%2Cclient%2Ccookie%2CembedPlayer%2CgetAttrs%2ChighlightText%2CloadingSpinner%2CmwEmbedUtil%2Csuggestions%2CtabIndex%2CtextSelection%2Cthrottle-debounce%2CtriggerQueueCallback%7Cjquery.uls.data%7Cmediawiki.RegExp%2CString%2CTitle%2CUri%2Capi%2Cbase%2Ccldr%2Ccookie%2Cexperiments%2CjqueryMsg%2Clanguage%2Cnotify%2CsearchSuggest%2Cstorage%2Ctemplate%2Ctoc%2Cuser%2Cutil%7Cmediawiki.editfont.styles%7Cmediawiki.language.months%7Cmediawiki.legacy.wikibits%7Cmediawiki.libs.pluralruleparser%7Cmediawiki.page.ready%2Cstartup%7Cmediawiki.template.regexp%7Cmediawiki.ui.button%2Cicon%7Cmmv.bootstrap%2Chead%7Cmmv.bootstrap.autostart%7Cmw.EmbedPlayer.loader%7Cmw.MediaWikiPlayer.loader%7Cmw.MwEmbedSupport%2CPopUpMediaTransform%7Cmw.MwEmbedSupport.style%7Cmw.PopUpMediaTransform.styles%7Cmw.TMHGalleryHook.js%7Cmw.TimedText.loader%7Coojs-ui-core.styles%7Coojs-ui.styles.icons-alerts%2Cicons-content%2Cicons-interactions%2Cindicators%2Ctextures%7Cskins.vector.js%7Cuser.defaults&skin=vector&version=1p3uzm9 (145)
-[0222/114722.043:INFO:CONSOLE(510)] "This page is using the deprecated ResourceLoader module "jquery.throttle-debounce".
-Please use OO.ui.throttle/debounce instead. See https://phabricator.wikimedia.org/T213426", source: https://en.wiktionary.org/w/load.php?debug=false&lang=en&modules=Spinner%2Cjquery%2Coojs%2Coojs-ui-core%2Csite%7Cext.centralNotice.choiceData%2Cdisplay%2CgeoIP%2CimpressionDiet%2CkvStore%2CkvStoreMaintenance%2ClegacySupport%2CstartUp%7Cext.centralauth.centralautologin%7Cext.eventLogging%2CnavigationTiming%2CwikimediaEvents%7Cext.eventLogging.subscriber%7Cext.uls.common%2Ccompactlinks%2Ceventlogger%2Cinit%2Cinterface%2Cpreferences%2Cwebfonts%7Cext.visualEditor.desktopArticleTarget.init%7Cext.visualEditor.progressBarWidget%2CsupportCheck%2CtargetLoader%2CtempWikitextEditorWidget%2Ctrack%2Cve%7Cjquery.accessKeyLabel%2CcheckboxShiftClick%2Cclient%2Ccookie%2CembedPlayer%2CgetAttrs%2ChighlightText%2CloadingSpinner%2CmwEmbedUtil%2Csuggestions%2CtabIndex%2CtextSelection%2Cthrottle-debounce%2CtriggerQueueCallback%7Cjquery.uls.data%7Cmediawiki.RegExp%2CString%2CTitle%2CUri%2Capi%2Cbase%2Ccldr%2Ccookie%2Cexperiments%2CjqueryMsg%2Clanguage%2Cnotify%2CsearchSuggest%2Cstorage%2Ctemplate%2Ctoc%2Cuser%2Cutil%7Cmediawiki.editfont.styles%7Cmediawiki.language.months%7Cmediawiki.legacy.wikibits%7Cmediawiki.libs.pluralruleparser%7Cmediawiki.page.ready%2Cstartup%7Cmediawiki.template.regexp%7Cmediawiki.ui.button%2Cicon%7Cmmv.bootstrap%2Chead%7Cmmv.bootstrap.autostart%7Cmw.EmbedPlayer.loader%7Cmw.MediaWikiPlayer.loader%7Cmw.MwEmbedSupport%2CPopUpMediaTransform%7Cmw.MwEmbedSupport.style%7Cmw.PopUpMediaTransform.styles%7Cmw.TMHGalleryHook.js%7Cmw.TimedText.loader%7Coojs-ui-core.styles%7Coojs-ui.styles.icons-alerts%2Cicons-content%2Cicons-interactions%2Cindicators%2Ctextures%7Cskins.vector.js%7Cuser.defaults&skin=vector&version=1p3uzm9 (510)
-[0222/114723.655:INFO:CONSOLE(24)] "This page is using the deprecated ResourceLoader module "jquery.ui.widget".", source: https://en.wiktionary.org/w/load.php?debug=false&lang=en&modules=jquery.ui.core%2Cmouse%2Cslider%2Cwidget%7Cjquery.ui.core.styles&skin=vector&version=0ramari (24)
-[0222/114723.706:INFO:CONSOLE(1)] "This page is using the deprecated ResourceLoader module "jquery.ui.core".
-Please use OOUI instead.", source: https://en.wiktionary.org/w/load.php?debug=false&lang=en&modules=jquery.ui.core%2Cmouse%2Cslider%2Cwidget%7Cjquery.ui.core.styles&skin=vector&version=0ramari (1)
-[0222/114723.941:INFO:CONSOLE(145)] "JQMIGRATE: jQuery.fn.unbind() is deprecated", source: https://en.wiktionary.org/w/load.php?debug=false&lang=en&modules=Spinner%2Cjquery%2Coojs%2Coojs-ui-core%2Csite%7Cext.centralNotice.choiceData%2Cdisplay%2CgeoIP%2CimpressionDiet%2CkvStore%2CkvStoreMaintenance%2ClegacySupport%2CstartUp%7Cext.centralauth.centralautologin%7Cext.eventLogging%2CnavigationTiming%2CwikimediaEvents%7Cext.eventLogging.subscriber%7Cext.uls.common%2Ccompactlinks%2Ceventlogger%2Cinit%2Cinterface%2Cpreferences%2Cwebfonts%7Cext.visualEditor.desktopArticleTarget.init%7Cext.visualEditor.progressBarWidget%2CsupportCheck%2CtargetLoader%2CtempWikitextEditorWidget%2Ctrack%2Cve%7Cjquery.accessKeyLabel%2CcheckboxShiftClick%2Cclient%2Ccookie%2CembedPlayer%2CgetAttrs%2ChighlightText%2CloadingSpinner%2CmwEmbedUtil%2Csuggestions%2CtabIndex%2CtextSelection%2Cthrottle-debounce%2CtriggerQueueCallback%7Cjquery.uls.data%7Cmediawiki.RegExp%2CString%2CTitle%2CUri%2Capi%2Cbase%2Ccldr%2Ccookie%2Cexperiments%2CjqueryMsg%2Clanguage%2Cnotify%2CsearchSuggest%2Cstorage%2Ctemplate%2Ctoc%2Cuser%2Cutil%7Cmediawiki.editfont.styles%7Cmediawiki.language.months%7Cmediawiki.legacy.wikibits%7Cmediawiki.libs.pluralruleparser%7Cmediawiki.page.ready%2Cstartup%7Cmediawiki.template.regexp%7Cmediawiki.ui.button%2Cicon%7Cmmv.bootstrap%2Chead%7Cmmv.bootstrap.autostart%7Cmw.EmbedPlayer.loader%7Cmw.MediaWikiPlayer.loader%7Cmw.MwEmbedSupport%2CPopUpMediaTransform%7Cmw.MwEmbedSupport.style%7Cmw.PopUpMediaTransform.styles%7Cmw.TMHGalleryHook.js%7Cmw.TimedText.loader%7Coojs-ui-core.styles%7Coojs-ui.styles.icons-alerts%2Cicons-content%2Cicons-interactions%2Cindicators%2Ctextures%7Cskins.vector.js%7Cuser.defaults&skin=vector&version=1p3uzm9 (145)
-[0222/114751.319:INFO:CONSOLE(0)] "Failed to decode downloaded font: data:application/font-woff2,", source: https://www.creativebloq.com/3d/30-amazing-examples-webgl-action-6142954 (0)
-[0222/114751.750:INFO:CONSOLE(630)] "Uncaught SyntaxError: Invalid or unexpected token", source: https://www.creativebloq.com/3d/30-amazing-examples-webgl-action-6142954 (630)
-[0222/114907.831:INFO:CONSOLE(0)] "Mixed Content: The page at 'https://webglsamples.org/' was loaded over HTTPS, but requested an insecure stylesheet 'http://fonts.googleapis.com/css?family=Oleo+Script:400|Open+Sans:300,300italic,600,600italic,800'. This request has been blocked; the content must be served over HTTPS.", source: https://webglsamples.org/ (0)
-[0222/114908.084:WARNING:angle_platform_impl.cc(52)] compileToBinary(232):
-C:\fakepath(73,10-42): warning X3571: pow(f, e) will not work for negative f, use abs(f) or conditionally handle negative values if you expect them
-C:\fakepath(95,10-42): warning X3571: pow(f, e) will not work for negative f, use abs(f) or conditionally handle negative values if you expect them
-
-[0222/114916.361:WARNING:backend_impl.cc(1843)] Destroying invalid entry.
-[0222/114916.404:INFO:CONSOLE(0)] "Failed to decode downloaded font: data:application/font-woff2,", source: https://www.creativebloq.com/3d/30-amazing-examples-webgl-action-6142954 (0)
-[0222/114917.169:INFO:CONSOLE(630)] "Uncaught SyntaxError: Invalid or unexpected token", source: https://www.creativebloq.com/3d/30-amazing-examples-webgl-action-6142954 (630)
-[0222/114917.186:WARNING:backend_impl.cc(1843)] Destroying invalid entry.
-[0222/114918.493:INFO:CONSOLE(2)] "__path__", source: https://vanilla.futurecdn.net/creativebloq/102783/media/js/main.min.js (2)
-[0222/114918.778:INFO:CONSOLE(10)] "Event Tracking driver "ga" initialised", source: https://vanilla.futurecdn.net/creativebloq/102783/media/js/main.min.js (10)
-[0222/114918.779:INFO:CONSOLE(10)] "All Event Tracking drivers initialised", source: https://vanilla.futurecdn.net/creativebloq/102783/media/js/main.min.js (10)
-[0222/114919.864:INFO:CONSOLE(10)] "Upgrading IndexedDB database (fibet, 4) from version 0 to version 4", source: https://vanilla.futurecdn.net/creativebloq/102783/media/js/main.min.js (10)
-[0222/114919.872:INFO:CONSOLE(10)] "Upgrade complete", source: https://vanilla.futurecdn.net/creativebloq/102783/media/js/main.min.js (10)
-[0222/114920.505:INFO:CONSOLE(10)] "IndexedDB database (fibet, version 4) opened successfully", source: https://vanilla.futurecdn.net/creativebloq/102783/media/js/main.min.js (10)
-[0222/114920.512:INFO:CONSOLE(10)] "Event Tracking driver "indexedDB" initialised", source: https://vanilla.futurecdn.net/creativebloq/102783/media/js/main.min.js (10)
-[0222/114920.621:INFO:CONSOLE(10)] "Purging events before 1545632360 (Mon Dec 24 2018 11:49:20 GMT+0530 (India Standard Time))", source: https://vanilla.futurecdn.net/creativebloq/102783/media/js/main.min.js (10)
-[0222/114920.642:INFO:CONSOLE(15)] "__path__", source: https://vanilla.futurecdn.net/creativebloq/102783/media/js/header/header.js (15)
-[0222/114921.091:INFO:CONSOLE(9)] "Found country code cookie", source: https://vanilla.futurecdn.net/creativebloq/102783/media/js/header/header.js (9)
-[0222/114921.096:INFO:CONSOLE(9)] "Found country code cookie", source: https://vanilla.futurecdn.net/creativebloq/102783/media/js/header/header.js (9)
-[0222/114921.176:INFO:CONSOLE(9)] "Found country code cookie", source: https://vanilla.futurecdn.net/creativebloq/102783/media/js/header/header.js (9)
-[0222/114921.209:INFO:CONSOLE(9)] "Found country code cookie", source: https://vanilla.futurecdn.net/creativebloq/102783/media/js/header/header.js (9)
-[0222/114921.211:INFO:CONSOLE(9)] "Found country code cookie", source: https://vanilla.futurecdn.net/creativebloq/102783/media/js/header/header.js (9)
-[0222/114921.228:INFO:CONSOLE(30)] "::DOMContentLoaded at", source: https://www.creativebloq.com/3d/30-amazing-examples-webgl-action-6142954 (30)
-[0222/114922.062:INFO:CONSOLE(10)] "Purge complete: 0 records deleted", source: https://vanilla.futurecdn.net/creativebloq/102783/media/js/main.min.js (10)
-[0222/114922.071:INFO:CONSOLE(10)] "Purged old indexedDB entries", source: https://vanilla.futurecdn.net/creativebloq/102783/media/js/main.min.js (10)
-[0222/114923.373:INFO:CONSOLE(31)] "::PageLoad at", source: https://www.creativebloq.com/3d/30-amazing-examples-webgl-action-6142954 (31)
-[0222/114925.159:INFO:CONSOLE(1)] "Uncaught (in promise) TypeError: Cannot read property 'permission' of undefined", source: https://cdn.onesignal.com/sdks/OneSignalSDK.js (1)
-[0222/114925.695:INFO:CONSOLE(0)] "Refused to execute script from 'https://pixel.servebom.com/partner?cb=&svc=us&id=11&uid=93266dfc-2bdd-4c95-958e-c6b1867a32fd' because its MIME type ('image/png') is not executable.", source: https://www.creativebloq.com/3d/30-amazing-examples-webgl-action-6142954 (0)
-[0222/114926.534:INFO:CONSOLE(31)] "::BordeauxDone at", source: https://www.creativebloq.com/3d/30-amazing-examples-webgl-action-6142954 (31)
-[0222/114927.276:INFO:CONSOLE(3)] "digiTrustUser not defined", source: https://js-sec.indexww.com/ht/p/184056-80653137503528.js (3)
-[0222/114927.293:INFO:CONSOLE(3)] "digiTrustUser not defined", source: https://js-sec.indexww.com/ht/p/184056-80653137503528.js (3)
-[0222/114927.296:INFO:CONSOLE(3)] "digiTrustUser not defined", source: https://js-sec.indexww.com/ht/p/184056-80653137503528.js (3)
-[0222/114927.296:INFO:CONSOLE(3)] "digiTrustUser not defined", source: https://js-sec.indexww.com/ht/p/184056-80653137503528.js (3)
-[0222/114927.305:INFO:CONSOLE(3)] "digiTrustUser not defined", source: https://js-sec.indexww.com/ht/p/184056-80653137503528.js (3)
-[0222/114927.306:INFO:CONSOLE(3)] "digiTrustUser not defined", source: https://js-sec.indexww.com/ht/p/184056-80653137503528.js (3)
-[0222/114927.307:INFO:CONSOLE(3)] "digiTrustUser not defined", source: https://js-sec.indexww.com/ht/p/184056-80653137503528.js (3)
-[0222/114927.315:INFO:CONSOLE(3)] "digiTrustUser not defined", source: https://js-sec.indexww.com/ht/p/184056-80653137503528.js (3)
-[0222/114927.321:INFO:CONSOLE(3)] "digiTrustUser not defined", source: https://js-sec.indexww.com/ht/p/184056-80653137503528.js (3)
-[0222/114928.008:INFO:CONSOLE(107)] "512", source: https://alteredqualia.com/three/examples/webgl_pasta.html (107)
-[0222/114928.117:INFO:CONSOLE(381)] "THREE.WebGLRenderer", source: https://alteredqualia.com/three/examples/js/three.min.pasta.js (381)
-[0222/114929.355:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114929.457:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114929.458:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114929.458:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114929.459:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114929.459:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114929.460:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114929.460:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114929.461:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114929.461:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114929.461:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114929.462:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114929.462:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114929.462:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114929.463:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114929.463:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114929.463:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114929.463:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114929.464:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114929.464:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114929.464:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114929.464:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114929.464:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114929.464:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114929.465:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114929.465:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114929.465:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114929.465:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114929.465:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114929.465:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114929.466:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114929.466:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114929.466:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114929.466:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114929.466:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114929.467:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114929.467:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114929.467:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114929.467:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114929.467:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114929.467:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114929.468:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114929.468:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114929.468:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114929.468:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114929.468:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114929.468:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114929.469:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114929.469:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114929.469:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114929.469:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114929.470:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114929.470:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114929.470:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114929.471:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114929.471:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114929.471:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114929.471:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114929.471:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114929.472:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114929.472:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114929.472:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114929.472:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114929.473:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114929.473:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114929.473:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114929.474:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114929.476:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114929.476:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114929.476:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114929.477:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114929.477:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114929.477:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114929.477:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114929.478:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114929.478:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114929.478:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114929.478:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114929.478:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114929.479:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114929.479:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114929.479:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114929.479:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114929.479:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114929.480:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114929.480:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114929.480:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114929.480:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114929.480:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114929.481:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114929.481:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114929.481:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114929.481:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114929.482:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114929.482:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114929.482:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114929.483:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114929.483:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114929.507:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114929.525:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114929.565:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114929.570:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114929.571:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114929.572:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114929.573:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114929.573:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114929.574:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114929.575:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114929.611:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114929.576:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114929.627:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114929.627:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114929.649:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114929.649:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114929.655:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114929.656:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114929.656:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114929.657:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114929.657:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114929.655:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114929.671:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114929.670:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114929.674:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114929.673:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114929.680:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114929.678:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114929.686:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114929.686:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114929.688:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114929.687:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114929.688:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114929.690:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114929.690:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114929.700:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114929.700:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114929.703:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114929.704:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114929.707:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114929.706:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114929.713:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114929.712:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114929.714:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114929.714:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114929.735:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114929.737:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114929.738:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114929.739:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114929.739:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114929.764:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114929.765:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114929.765:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114929.766:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114929.766:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114929.766:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114929.766:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114929.764:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114929.773:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114929.771:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114929.774:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114929.774:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114929.776:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114929.777:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114929.778:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114929.778:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114929.782:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114929.780:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114929.786:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114929.788:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114929.790:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114929.789:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114929.791:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114929.793:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114929.793:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114929.795:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114929.796:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114929.798:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114929.799:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114929.801:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114929.802:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114929.807:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114929.808:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114929.809:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114929.811:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114929.811:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114929.800:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114929.812:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114929.815:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114929.814:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114929.816:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114929.817:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114929.817:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114929.818:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114929.822:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114929.821:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114929.823:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114929.823:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114929.824:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114929.825:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114929.825:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114929.827:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114929.827:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114929.828:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114929.829:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114929.829:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114929.833:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114929.833:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114929.832:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114929.835:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114929.834:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114929.837:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114929.837:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114929.839:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114929.838:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114929.840:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114929.840:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114929.843:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114929.842:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114929.845:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114929.844:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114929.846:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114929.846:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114929.847:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114929.845:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114929.850:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114929.850:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114929.848:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114929.854:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114929.851:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114929.856:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114929.855:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114929.857:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114929.856:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114929.858:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114929.858:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114929.862:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114929.867:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114929.864:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114929.868:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114929.867:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114929.869:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114929.871:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114929.874:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114929.872:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114929.875:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114929.876:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114929.879:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114929.879:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114929.881:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114929.880:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114929.886:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114929.885:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114929.888:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114929.887:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114929.891:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114929.889:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114929.893:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114929.892:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114929.895:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114929.894:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114929.897:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114929.896:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114929.899:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114929.898:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114929.900:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114929.901:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114929.926:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114929.927:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114929.927:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114929.933:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114929.932:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114929.958:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114929.961:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114929.959:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114929.962:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114929.964:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114929.967:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114929.965:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114929.968:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114929.970:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114929.972:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114929.976:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114929.974:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114929.978:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114929.977:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114929.980:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114929.979:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114929.981:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114929.982:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114929.986:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114929.983:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114929.989:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114929.987:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114929.989:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114929.992:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114929.995:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114929.994:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114929.998:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114929.996:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114930.000:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114929.998:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114930.002:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114930.000:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114930.003:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114930.004:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114930.008:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114930.010:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114930.012:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114930.011:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114930.014:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114930.013:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114930.016:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114930.017:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114930.015:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114930.018:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114930.019:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114930.020:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114930.020:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114930.020:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114930.021:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114930.019:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114930.023:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114930.023:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114930.025:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114930.025:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114930.026:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114930.024:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114930.055:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114930.056:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114930.056:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114930.056:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114930.057:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114930.055:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114930.066:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114930.066:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114930.066:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114930.067:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114930.067:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114930.067:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114930.068:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114930.068:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114930.068:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114930.069:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114930.069:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114930.065:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114930.082:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114930.082:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114930.084:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114930.083:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114930.094:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114930.096:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114930.096:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114930.096:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114930.109:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114930.109:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114930.117:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114930.117:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114930.118:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114930.119:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114930.119:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114930.119:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114930.120:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114930.120:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114930.120:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114930.121:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114930.121:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114930.121:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114930.122:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114930.122:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114930.118:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114930.142:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114930.143:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114930.143:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114930.145:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114930.144:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114930.153:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114930.155:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114930.155:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114930.155:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114930.153:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114930.158:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114930.158:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114930.166:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114930.169:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114930.166:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114930.170:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114930.170:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114930.171:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114930.171:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114930.173:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114930.173:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114930.173:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114930.174:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114930.174:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114930.174:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114930.174:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114930.175:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114930.171:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114930.178:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114930.188:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114930.178:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114930.191:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114930.189:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114930.203:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114930.202:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114930.208:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114930.208:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114930.213:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114930.212:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114930.214:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114930.216:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114930.216:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114930.218:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114930.218:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114930.221:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114930.221:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114930.246:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114930.264:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114930.247:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114930.265:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114930.267:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114930.268:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114930.269:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114930.267:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114930.270:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114930.270:ERROR:gles2_cmd_decoder.cc(10276)] [.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0
-[0222/114930.271:ERROR:logger.cc(47)] Too many GL errors, not reporting any more for this context. use --disable-gl-error-limit to see all errors.
-[0222/114930.270:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114930.331:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114930.340:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114930.340:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114930.347:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114930.349:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114930.373:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114930.381:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114930.384:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114930.386:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114930.387:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114930.388:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114930.389:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114930.390:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114930.391:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114930.392:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114930.395:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114930.396:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114930.399:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114930.403:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114930.404:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114930.405:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114930.406:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114930.408:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114930.410:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114930.412:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114930.413:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114930.414:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114930.415:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114930.420:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114930.421:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114930.424:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114930.427:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114930.428:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114930.430:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114930.432:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114930.433:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114930.434:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114930.435:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114930.435:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114930.436:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114930.437:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114930.438:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114930.439:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114930.439:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114930.440:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114930.440:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114930.441:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114930.442:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114930.442:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114930.443:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114930.444:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114930.445:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114930.446:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114930.447:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114930.447:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114930.448:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114930.449:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114930.449:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114930.450:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114930.451:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114930.451:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114930.452:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114930.452:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114930.453:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114930.454:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114930.454:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114930.455:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114930.455:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114930.456:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114930.456:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114930.457:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114930.458:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114930.458:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114930.459:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114930.460:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114930.461:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114930.462:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114930.463:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114930.464:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114930.465:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114930.467:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114930.468:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114930.469:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114930.471:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114930.472:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114930.473:INFO:CONSOLE(0)] "[.WebGL-08E04010]RENDER WARNING: there is no texture bound to the unit 0", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
-[0222/114930.474:INFO:CONSOLE(0)] "WebGL: too many errors, no more errors will be reported to the console for this context.", source: https://alteredqualia.com/three/examples/webgl_pasta.html (0)
diff --git a/src/bin/devtools_resources.pak b/src/bin/devtools_resources.pak
deleted file mode 100644
index 665807e..0000000
Binary files a/src/bin/devtools_resources.pak and /dev/null differ
diff --git a/src/bin/icudtl.dat b/src/bin/icudtl.dat
deleted file mode 100644
index 63de9d5..0000000
Binary files a/src/bin/icudtl.dat and /dev/null differ
diff --git a/src/bin/libEGL.dll b/src/bin/libEGL.dll
deleted file mode 100644
index e6f2ad5..0000000
Binary files a/src/bin/libEGL.dll and /dev/null differ
diff --git a/src/bin/libGLESv2.dll b/src/bin/libGLESv2.dll
deleted file mode 100644
index 253df68..0000000
Binary files a/src/bin/libGLESv2.dll and /dev/null differ
diff --git a/src/bin/libcef.dll b/src/bin/libcef.dll
deleted file mode 100644
index 4663cf8..0000000
Binary files a/src/bin/libcef.dll and /dev/null differ
diff --git a/src/bin/locales/am.pak b/src/bin/locales/am.pak
deleted file mode 100644
index 3c7332e..0000000
Binary files a/src/bin/locales/am.pak and /dev/null differ
diff --git a/src/bin/locales/ar.pak b/src/bin/locales/ar.pak
deleted file mode 100644
index 479bb51..0000000
Binary files a/src/bin/locales/ar.pak and /dev/null differ
diff --git a/src/bin/locales/bg.pak b/src/bin/locales/bg.pak
deleted file mode 100644
index f8de888..0000000
Binary files a/src/bin/locales/bg.pak and /dev/null differ
diff --git a/src/bin/locales/bn.pak b/src/bin/locales/bn.pak
deleted file mode 100644
index 4c2557b..0000000
Binary files a/src/bin/locales/bn.pak and /dev/null differ
diff --git a/src/bin/locales/ca.pak b/src/bin/locales/ca.pak
deleted file mode 100644
index d6aed82..0000000
Binary files a/src/bin/locales/ca.pak and /dev/null differ
diff --git a/src/bin/locales/cs.pak b/src/bin/locales/cs.pak
deleted file mode 100644
index cf237b3..0000000
Binary files a/src/bin/locales/cs.pak and /dev/null differ
diff --git a/src/bin/locales/da.pak b/src/bin/locales/da.pak
deleted file mode 100644
index a620497..0000000
Binary files a/src/bin/locales/da.pak and /dev/null differ
diff --git a/src/bin/locales/de.pak b/src/bin/locales/de.pak
deleted file mode 100644
index 25579ea..0000000
Binary files a/src/bin/locales/de.pak and /dev/null differ
diff --git a/src/bin/locales/el.pak b/src/bin/locales/el.pak
deleted file mode 100644
index a5e0441..0000000
Binary files a/src/bin/locales/el.pak and /dev/null differ
diff --git a/src/bin/locales/en-GB.pak b/src/bin/locales/en-GB.pak
deleted file mode 100644
index d24de86..0000000
Binary files a/src/bin/locales/en-GB.pak and /dev/null differ
diff --git a/src/bin/locales/en-US.pak b/src/bin/locales/en-US.pak
deleted file mode 100644
index 0d06eae..0000000
Binary files a/src/bin/locales/en-US.pak and /dev/null differ
diff --git a/src/bin/locales/es-419.pak b/src/bin/locales/es-419.pak
deleted file mode 100644
index 464ebac..0000000
Binary files a/src/bin/locales/es-419.pak and /dev/null differ
diff --git a/src/bin/locales/es.pak b/src/bin/locales/es.pak
deleted file mode 100644
index c67d953..0000000
Binary files a/src/bin/locales/es.pak and /dev/null differ
diff --git a/src/bin/locales/et.pak b/src/bin/locales/et.pak
deleted file mode 100644
index beec99a..0000000
Binary files a/src/bin/locales/et.pak and /dev/null differ
diff --git a/src/bin/locales/fa.pak b/src/bin/locales/fa.pak
deleted file mode 100644
index 563f2e3..0000000
Binary files a/src/bin/locales/fa.pak and /dev/null differ
diff --git a/src/bin/locales/fi.pak b/src/bin/locales/fi.pak
deleted file mode 100644
index 3c667a0..0000000
Binary files a/src/bin/locales/fi.pak and /dev/null differ
diff --git a/src/bin/locales/fil.pak b/src/bin/locales/fil.pak
deleted file mode 100644
index 4b84d01..0000000
Binary files a/src/bin/locales/fil.pak and /dev/null differ
diff --git a/src/bin/locales/fr.pak b/src/bin/locales/fr.pak
deleted file mode 100644
index a96eecf..0000000
Binary files a/src/bin/locales/fr.pak and /dev/null differ
diff --git a/src/bin/locales/gu.pak b/src/bin/locales/gu.pak
deleted file mode 100644
index db6910d..0000000
Binary files a/src/bin/locales/gu.pak and /dev/null differ
diff --git a/src/bin/locales/he.pak b/src/bin/locales/he.pak
deleted file mode 100644
index 2848810..0000000
Binary files a/src/bin/locales/he.pak and /dev/null differ
diff --git a/src/bin/locales/hi.pak b/src/bin/locales/hi.pak
deleted file mode 100644
index 82f29b2..0000000
Binary files a/src/bin/locales/hi.pak and /dev/null differ
diff --git a/src/bin/locales/hr.pak b/src/bin/locales/hr.pak
deleted file mode 100644
index 892e5b7..0000000
Binary files a/src/bin/locales/hr.pak and /dev/null differ
diff --git a/src/bin/locales/hu.pak b/src/bin/locales/hu.pak
deleted file mode 100644
index 98a2776..0000000
Binary files a/src/bin/locales/hu.pak and /dev/null differ
diff --git a/src/bin/locales/id.pak b/src/bin/locales/id.pak
deleted file mode 100644
index 7e8e5b4..0000000
Binary files a/src/bin/locales/id.pak and /dev/null differ
diff --git a/src/bin/locales/it.pak b/src/bin/locales/it.pak
deleted file mode 100644
index c08b372..0000000
Binary files a/src/bin/locales/it.pak and /dev/null differ
diff --git a/src/bin/locales/ja.pak b/src/bin/locales/ja.pak
deleted file mode 100644
index 99ac0ff..0000000
Binary files a/src/bin/locales/ja.pak and /dev/null differ
diff --git a/src/bin/locales/kn.pak b/src/bin/locales/kn.pak
deleted file mode 100644
index ebc7610..0000000
Binary files a/src/bin/locales/kn.pak and /dev/null differ
diff --git a/src/bin/locales/ko.pak b/src/bin/locales/ko.pak
deleted file mode 100644
index abff731..0000000
Binary files a/src/bin/locales/ko.pak and /dev/null differ
diff --git a/src/bin/locales/lt.pak b/src/bin/locales/lt.pak
deleted file mode 100644
index f537c56..0000000
Binary files a/src/bin/locales/lt.pak and /dev/null differ
diff --git a/src/bin/locales/lv.pak b/src/bin/locales/lv.pak
deleted file mode 100644
index a237257..0000000
Binary files a/src/bin/locales/lv.pak and /dev/null differ
diff --git a/src/bin/locales/ml.pak b/src/bin/locales/ml.pak
deleted file mode 100644
index 9049223..0000000
Binary files a/src/bin/locales/ml.pak and /dev/null differ
diff --git a/src/bin/locales/mr.pak b/src/bin/locales/mr.pak
deleted file mode 100644
index a092f94..0000000
Binary files a/src/bin/locales/mr.pak and /dev/null differ
diff --git a/src/bin/locales/ms.pak b/src/bin/locales/ms.pak
deleted file mode 100644
index d4763fd..0000000
Binary files a/src/bin/locales/ms.pak and /dev/null differ
diff --git a/src/bin/locales/nb.pak b/src/bin/locales/nb.pak
deleted file mode 100644
index b258569..0000000
Binary files a/src/bin/locales/nb.pak and /dev/null differ
diff --git a/src/bin/locales/nl.pak b/src/bin/locales/nl.pak
deleted file mode 100644
index 944b757..0000000
Binary files a/src/bin/locales/nl.pak and /dev/null differ
diff --git a/src/bin/locales/pl.pak b/src/bin/locales/pl.pak
deleted file mode 100644
index 5f367bd..0000000
Binary files a/src/bin/locales/pl.pak and /dev/null differ
diff --git a/src/bin/locales/pt-BR.pak b/src/bin/locales/pt-BR.pak
deleted file mode 100644
index 129ed32..0000000
Binary files a/src/bin/locales/pt-BR.pak and /dev/null differ
diff --git a/src/bin/locales/pt-PT.pak b/src/bin/locales/pt-PT.pak
deleted file mode 100644
index 710ebf2..0000000
Binary files a/src/bin/locales/pt-PT.pak and /dev/null differ
diff --git a/src/bin/locales/ro.pak b/src/bin/locales/ro.pak
deleted file mode 100644
index 5a36136..0000000
Binary files a/src/bin/locales/ro.pak and /dev/null differ
diff --git a/src/bin/locales/ru.pak b/src/bin/locales/ru.pak
deleted file mode 100644
index 691b7a4..0000000
Binary files a/src/bin/locales/ru.pak and /dev/null differ
diff --git a/src/bin/locales/sk.pak b/src/bin/locales/sk.pak
deleted file mode 100644
index 7a869e3..0000000
Binary files a/src/bin/locales/sk.pak and /dev/null differ
diff --git a/src/bin/locales/sl.pak b/src/bin/locales/sl.pak
deleted file mode 100644
index 10f0fa4..0000000
Binary files a/src/bin/locales/sl.pak and /dev/null differ
diff --git a/src/bin/locales/sr.pak b/src/bin/locales/sr.pak
deleted file mode 100644
index b3e5ce1..0000000
Binary files a/src/bin/locales/sr.pak and /dev/null differ
diff --git a/src/bin/locales/sv.pak b/src/bin/locales/sv.pak
deleted file mode 100644
index ae8ef41..0000000
Binary files a/src/bin/locales/sv.pak and /dev/null differ
diff --git a/src/bin/locales/sw.pak b/src/bin/locales/sw.pak
deleted file mode 100644
index f6660d0..0000000
Binary files a/src/bin/locales/sw.pak and /dev/null differ
diff --git a/src/bin/locales/ta.pak b/src/bin/locales/ta.pak
deleted file mode 100644
index d5b1790..0000000
Binary files a/src/bin/locales/ta.pak and /dev/null differ
diff --git a/src/bin/locales/te.pak b/src/bin/locales/te.pak
deleted file mode 100644
index 535b8f3..0000000
Binary files a/src/bin/locales/te.pak and /dev/null differ
diff --git a/src/bin/locales/th.pak b/src/bin/locales/th.pak
deleted file mode 100644
index fec80c2..0000000
Binary files a/src/bin/locales/th.pak and /dev/null differ
diff --git a/src/bin/locales/tr.pak b/src/bin/locales/tr.pak
deleted file mode 100644
index a60a8d3..0000000
Binary files a/src/bin/locales/tr.pak and /dev/null differ
diff --git a/src/bin/locales/uk.pak b/src/bin/locales/uk.pak
deleted file mode 100644
index 0aec6b4..0000000
Binary files a/src/bin/locales/uk.pak and /dev/null differ
diff --git a/src/bin/locales/vi.pak b/src/bin/locales/vi.pak
deleted file mode 100644
index 6f4dacd..0000000
Binary files a/src/bin/locales/vi.pak and /dev/null differ
diff --git a/src/bin/locales/zh-CN.pak b/src/bin/locales/zh-CN.pak
deleted file mode 100644
index e662170..0000000
Binary files a/src/bin/locales/zh-CN.pak and /dev/null differ
diff --git a/src/bin/locales/zh-TW.pak b/src/bin/locales/zh-TW.pak
deleted file mode 100644
index 6ff5e4b..0000000
Binary files a/src/bin/locales/zh-TW.pak and /dev/null differ
diff --git a/src/bin/natives_blob.bin b/src/bin/natives_blob.bin
deleted file mode 100644
index ccd7e80..0000000
Binary files a/src/bin/natives_blob.bin and /dev/null differ
diff --git a/src/bin/storage/action_link.css b/src/bin/net8.0-windows/storage/action_link.css
similarity index 100%
rename from src/bin/storage/action_link.css
rename to src/bin/net8.0-windows/storage/action_link.css
diff --git a/src/bin/net8.0-windows/storage/downloads.html b/src/bin/net8.0-windows/storage/downloads.html
new file mode 100644
index 0000000..8e6344f
--- /dev/null
+++ b/src/bin/net8.0-windows/storage/downloads.html
@@ -0,0 +1,189 @@
+
+
+
+
+ Downloads
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/bin/storage/errors/aboutNetError.css b/src/bin/net8.0-windows/storage/errors/aboutNetError.css
similarity index 100%
rename from src/bin/storage/errors/aboutNetError.css
rename to src/bin/net8.0-windows/storage/errors/aboutNetError.css
diff --git a/src/bin/storage/errors/aboutNetError_alert.svg b/src/bin/net8.0-windows/storage/errors/aboutNetError_alert.svg
similarity index 100%
rename from src/bin/storage/errors/aboutNetError_alert.svg
rename to src/bin/net8.0-windows/storage/errors/aboutNetError_alert.svg
diff --git a/src/bin/storage/errors/aboutNetError_info.svg b/src/bin/net8.0-windows/storage/errors/aboutNetError_info.svg
similarity index 100%
rename from src/bin/storage/errors/aboutNetError_info.svg
rename to src/bin/net8.0-windows/storage/errors/aboutNetError_info.svg
diff --git a/src/bin/storage/errors/cannotConnect.html b/src/bin/net8.0-windows/storage/errors/cannotConnect.html
similarity index 100%
rename from src/bin/storage/errors/cannotConnect.html
rename to src/bin/net8.0-windows/storage/errors/cannotConnect.html
diff --git a/src/bin/storage/errors/common.css b/src/bin/net8.0-windows/storage/errors/common.css
similarity index 100%
rename from src/bin/storage/errors/common.css
rename to src/bin/net8.0-windows/storage/errors/common.css
diff --git a/src/bin/storage/errors/notFound.html b/src/bin/net8.0-windows/storage/errors/notFound.html
similarity index 100%
rename from src/bin/storage/errors/notFound.html
rename to src/bin/net8.0-windows/storage/errors/notFound.html
diff --git a/src/bin/storage/errors/warning-16.png b/src/bin/net8.0-windows/storage/errors/warning-16.png
similarity index 100%
rename from src/bin/storage/errors/warning-16.png
rename to src/bin/net8.0-windows/storage/errors/warning-16.png
diff --git a/src/bin/storage/i18n_process.css b/src/bin/net8.0-windows/storage/i18n_process.css
similarity index 100%
rename from src/bin/storage/i18n_process.css
rename to src/bin/net8.0-windows/storage/i18n_process.css
diff --git a/src/bin/storage/jquery-1.10.2.min.js b/src/bin/net8.0-windows/storage/jquery-1.10.2.min.js
similarity index 100%
rename from src/bin/storage/jquery-1.10.2.min.js
rename to src/bin/net8.0-windows/storage/jquery-1.10.2.min.js
diff --git a/src/bin/storage/other.css b/src/bin/net8.0-windows/storage/other.css
similarity index 100%
rename from src/bin/storage/other.css
rename to src/bin/net8.0-windows/storage/other.css
diff --git a/src/bin/storage/progressbackground.png b/src/bin/net8.0-windows/storage/progressbackground.png
similarity index 100%
rename from src/bin/storage/progressbackground.png
rename to src/bin/net8.0-windows/storage/progressbackground.png
diff --git a/src/bin/storage/shared.css b/src/bin/net8.0-windows/storage/shared.css
similarity index 100%
rename from src/bin/storage/shared.css
rename to src/bin/net8.0-windows/storage/shared.css
diff --git a/src/bin/storage/text_defaults.css b/src/bin/net8.0-windows/storage/text_defaults.css
similarity index 100%
rename from src/bin/storage/text_defaults.css
rename to src/bin/net8.0-windows/storage/text_defaults.css
diff --git a/src/bin/storage/widgets.css b/src/bin/net8.0-windows/storage/widgets.css
similarity index 100%
rename from src/bin/storage/widgets.css
rename to src/bin/net8.0-windows/storage/widgets.css
diff --git a/src/bin/snapshot_blob.bin b/src/bin/snapshot_blob.bin
deleted file mode 100644
index 3d630b9..0000000
Binary files a/src/bin/snapshot_blob.bin and /dev/null differ
diff --git a/src/bin/storage/downloads.html b/src/bin/storage/downloads.html
deleted file mode 100644
index 6abfba3..0000000
--- a/src/bin/storage/downloads.html
+++ /dev/null
@@ -1,183 +0,0 @@
-
-
- Downloads
-
-
-
-
-
-
-
-