All Projects → mingyaulee → WebExtensions.Net

mingyaulee / WebExtensions.Net

Licence: MIT license
A package for consuming WebExtensions API in a browser extension.

Programming Languages

C#
18002 projects

Projects that are alternatives of or similar to WebExtensions.Net

Blazor.BrowserExtension
A package for building Browser Extension with Blazor WebAssembly application.
Stars: ✭ 207 (+840.91%)
Mutual labels:  browser-extension, blazor
DNTPersianComponents.Blazor
A collection of Persian components for Blazor
Stars: ✭ 27 (+22.73%)
Mutual labels:  blazor
BlazorDemo
Demo application for my writings about Blazor
Stars: ✭ 79 (+259.09%)
Mutual labels:  blazor
http-indicator
Indicator for HTTP/2, QUIC and HTTP/3
Stars: ✭ 52 (+136.36%)
Mutual labels:  browser-extension
gitlab-notify-extension
🦊 Gitlab Browser Extension (Chrome & Firefox). Don't miss any Gitlab Merge Requests and rocket up your productivity.
Stars: ✭ 65 (+195.45%)
Mutual labels:  browser-extension
purple-pi
💜 LaTeX math wherever you want
Stars: ✭ 31 (+40.91%)
Mutual labels:  browser-extension
Blazor.AdaptiveCards
Adaptive Cards for Blazor
Stars: ✭ 45 (+104.55%)
Mutual labels:  blazor
MudBlazor.Markdown
Markdown component based on the MudBlazor environment
Stars: ✭ 30 (+36.36%)
Mutual labels:  blazor
Blazorous
Maintainable CSS with Blazor
Stars: ✭ 48 (+118.18%)
Mutual labels:  blazor
copy-as-markdown
🖱 Browser extension to copy hyperlinks, images, and selected text as Markdown with GFM support
Stars: ✭ 137 (+522.73%)
Mutual labels:  browser-extension
AutoSaveEditForm
A replacement for the default EditForm component which will auto save a form until it is successfully submitted
Stars: ✭ 44 (+100%)
Mutual labels:  blazor
csgo-trader-extension
CSGO Trader Browser Extension to help with CS:GO item trading, marketing and much more
Stars: ✭ 86 (+290.91%)
Mutual labels:  browser-extension
youtube-video-quality
Watch YouTube in your preferred video quality
Stars: ✭ 37 (+68.18%)
Mutual labels:  browser-extension
BlazorGraphApi
Blazor Server App with Azure AD Authentication, that calls the Microsoft Graph API on-behalf of the signed-in user.
Stars: ✭ 28 (+27.27%)
Mutual labels:  blazor
blazor-adminlte
This project adapts ADMINLTE 3 so the components can be used from dotnet core Blazor / Server / Web Assembly
Stars: ✭ 182 (+727.27%)
Mutual labels:  blazor
url-incrementer
A web extension for Chrome, Edge, and Firefox. Increment a URL or go to the next page. Supports auto incrementing and advanced toolkit functions like scraping URLs.
Stars: ✭ 27 (+22.73%)
Mutual labels:  browser-extension
blazor-tasks
Blazor example To-Do App
Stars: ✭ 33 (+50%)
Mutual labels:  blazor
night-video-tuner
🎬 Browser extension that allows adjusting temperature and other properties of videos on Chrome and Firefox.
Stars: ✭ 19 (-13.64%)
Mutual labels:  browser-extension
SyncfusionHelpDeskClient
Syncfusion Help Desk WebAssembly
Stars: ✭ 15 (-31.82%)
Mutual labels:  blazor
stylish-hub
🍹 A browser extension that brings new GitHub features and experience.
Stars: ✭ 14 (-36.36%)
Mutual labels:  browser-extension

WebExtensions.Net

Nuget GitHub Workflow Status Sonar Tests Sonar Quality Gate

A package for consuming WebExtensions API in a browser extension.

These API classes are generated based on the Mozilla documentation for WebExtensions API.

How to use this package

Important for v0.*.*:
This package is still in pre-release stage so the versioning does not comply with semantic versioning. Feature and bug fix increments the patch version and breaking change increments the minor version. So be sure to check the release note before upgrading between minor version.

This package can be consumed in two methods.

With Blazor (Recommended)

Create a browser extension using Blazor. Refer to the package Blazor.BrowserExtension to get started.

Without Blazor

Create a standard browser extension using JavaScript and load the WebAssembly manually. The .Net source code can be compiled into wasm using Mono.

  1. Install WebExtensions.Net (if you intend to use the API without dependency injection) or WebExtensions.Net.Extensions.DependencyInjection from Nuget.
  2. Import the JsBind.Net scripts with <script src="_content/JsBind.Net/JsBindNet.js"></script>. If your project does not support Razor Class Library contents, add the property <LinkJsBindAssets>true</LinkJsBindAssets> to your project.
  3. Import the WebExtensions polyfill by Mozilla for cross browser compatibility. This polyfill helps to convert the callback based Chrome extensions API to a Promise based API for asynchronous functions.
  4. Consume the WebExtensions API by creating an instance of WebExtensionsApi as shown below.
using JsBind.Net;
using JsBind.Net.Configurations;
using WebExtensions.Net;
...
var options = new JsBindOptionsConfigurator()
    .UseInProcessJsRuntime()
    .Options;
// iJsRuntime is an instance of MonoWebAssemblyJSRuntime
var jsRuntimeAdapter = new JsRuntimeAdapter(iJsRuntime, options);
var webExtensionsApi = new WebExtensionsApi(jsRuntimeAdapter);
// Use the WebExtensions API
var manifest = await webExtensionsApi.Runtime.GetManifest();

Debugging and testing

For the purpose of debugging and testing outside of the browser extension environment, there is a MockJsRuntimeAdapter class under the WebExtensions.Net.Mock namespace. Initialize an instance of the mock API with:

using WebExtensions.Net;
using WebExtensions.Net.Mock;
...
var jsRuntimeAdapter = new MockJsRuntimeAdapter();
var webExtensionsApi = new WebExtensionsApi(jsRuntimeAdapter);

To configure the behaviour of the mock API, you may use any combination of the following:

MockResolvers.Configure(configure =>
{
    // configure a method without any argument
    configure.Api.Method<string>(api => api.Runtime.GetId).Returns(() => "MyExtensionId");
    // or
    configure.Api.Method<string>(api => api.Runtime.GetId).ReturnsForAnyArgs("MyExtensionId");

    // configure a method with one argument
    configure.Api.Method<string, string>(api => api.Runtime.GetURL).Returns(path => builder.HostEnvironment.BaseAddress + path);

    // configure a method that returns the same object regardless of the arguments
    configure.Api.Method<string, CreateNotificationOptions, string>(api => api.Notifications.Create).ReturnsForAnyArgs("NotificationId");

    // configure an action to be invoked when an API is called
    configure.Api.Method<int?>(api => api.Tabs.GoForward).Invokes(tabId => { /* Do something with tabId */ });

    // configure a method on an object reference
    using var emptyJson = JsonDocument.Parse("{}");
    configure.ObjectReference(DefaultMockObjects.LocalStorage).Method<StorageAreaGetKeys, JsonElement>(storage => storage.Get).ReturnsForAnyArgs(emptyJson.RootElement.Clone());

    // configure an action to be invoked when a method on an object reference is called
    configure.ObjectReference(DefaultMockObjects.LocalStorage).Method(storage => storage.Clear).Invokes(() => { /* Do something */ });

    // configure a generic delegate to handle all the API calls
    bool apiHandler(string targetPath, object[] arguments, out object result)
    {
        if (targetPath == "runtime.id")
        {
            result = "MyExtensionId";
            return true;
        }
        result = null;
        return false;
    }
    configure.ApiHandler(apiHandler);

    // configure a generic delegate to handle all the invocations to object references
    bool objectReferenceHandler(object objectReference, string targetPath, object[] arguments, out object result)
    {
        if (objectReference == DefaultMockObjects.LocalStorage && targetPath == "get")
        {
            using var emptyJson = JsonDocument.Parse("{}");
            result = emptyJson.RootElement.Clone();
            return true;
        }
        result = null;
        return false;
    }
    configure.ObjectReferenceHandler(objectReferenceHandler);
});

Note: The sequence of mock registration matters. Overall the more specific method Returns and ReturnsForAnyArgs is prioritized over the generic delegate ApiHandler and ObjectReferenceHandler. If there exists registration that handles the same API or object reference call, the last registered handler will be used. For example:

MockResolvers.Configure(configure =>
{
    // when api.Runtime.GetId is called it will return "MyExtensionId2"
    configure.Api.Method<string>(api => api.Runtime.GetId).Returns(() => "MyExtensionId1");
    configure.Api.Method<string>(api => api.Runtime.GetId).Returns(() => "MyExtensionId2");
});
MockResolvers.Configure(configure =>
{
    // when api.Runtime.GetId is called it will return "MyExtensionId1", even though the generic API handler is registered last, the more specific method registration is prioritized.
    configure.Api.Method<string>(api => api.Runtime.GetId).Returns(() => "MyExtensionId1");

    bool apiHandler(string targetPath, object[] arguments, out object result)
    {
        if (targetPath == "runtime.id")
        {
            result = "MyExtensionId2";
            return true;
        }
        result = null;
        return false;
    }
    configure.ApiHandler(apiHandler);
});

API References

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].