Giter Club home page Giter Club logo

jsbrowser's Introduction

Logo JavaScript Browser

A web browser built with JavaScript as a Windows app.
http://microsoftedge.github.io/JSBrowser/

badge_windowsstore

JavaScript Browser

This project is a tutorial demonstrating the capabilities of the web platform on Windows 10. The browser is a sample app built around the HTML WebView control, using primarily JavaScript to light up the user interface. Built using Visual Studio 2015, this is a JavaScript Universal Windows Platform (UWP) app.

In addition to JavaScript, HTML and CSS are the other core programming languages used. Some C++ code is also included to enable supplemental features, but is not required to create a simple browser.

Additionally, we’re taking advantage of the new ECMAScript 2015 (ES2015) support in Chakra, the JavaScript engine behind Microsoft Edge and the WebView control. ES2015 allows us to remove much of the scaffolding and boilerplate code, simplifying our implementation significantly. The following ES2015 features were used in the creation of this app: Array.from(), Array.prototype.find(), arrow functions, method properties, const, for-of, let, Map, Object.assign(), Promises, property shorthands, Proxies, spread operator, String.prototype.includes(), String.prototype.startsWith(), Symbols, template strings, and Unicode code point escapes.

User interface

The user interface consists of ten components:

  • Title bar
  • Back button
  • Forward button
  • Refresh button
  • Favicon
  • Address bar
  • Share on Twitter button
  • Favorites button and menu
  • Settings button and menu
  • WebView control

Favorites

Additional functionality

There are several additional features implemented to make the browsing experience more pleasant:

  • Keyboard shortcuts - press F11 to toggle fullscreen mode, ESC to exit fullscreen mode, or Ctrl + L to select the address bar
  • CSS transitions for animating the menus
  • Cache management
  • Favorites management
  • URL input analysis — “bing.com” navigates to http(s)://bing.com, “seahawks” searches Bing
  • Auto-de/select the address bar on blur/focus
  • Responsive design

Harnessing the WebView control

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

Introduced for JavaScript apps in Windows 8.1, the WebView control—sometimes referred to by its tag name, x-ms-webview—allows you to host web content in your Windows app. Available in both HTML and XAML, the x-ms-webview comes with a powerful set of APIs, which overcomes several of the limitations that encumber an iframe, such as framebusting sites and document loading events. Additionally, the x-ms-webview provides new functionality that is not possible with an iframe, such as better access to local content and the ability to take screenshots.

When you use the WebView control, you get the same web platform that powers Microsoft Edge.

WebView flowchart

Developing the browser

We will be using fifteen of the x-ms-webview APIs. All but two of these members handle the page navigation in some capacity. Let’s see how we can hook into these APIs to create each UI component.

Hooking up the back and forward buttons

When you invoke a back button, the browser returns to an earlier page in the browser history, if available. Similarly, when you invoke a forward button, the browser returns to a later page in the browser history, if available. In order to implement this logic, we use the goBack() and goForward() methods, respectively. These functions will automatically navigate to the correct page in the navigation stack.

After every page navigation, we will also update the current state to stop the user from navigating further when they reach either end of the navigation stack. This will disable the back or forward buttons when the canGoBack property or the canGoForward property resolves false, respectively.

// Update the navigation state
this.updateNavState = () => {
  this.backButton.disabled = !this.webview.canGoBack;
  this.forwardButton.disabled = !this.webview.canGoForward;
};

// Listen for the back button to navigate backwards
this.backButton.addEventListener("click", () => this.webview.goBack());

// Listen for the forward button to navigate forwards
this.forwardButton.addEventListener("click", () => this.webview.goForward());

Hooking up the refresh and stop buttons

The refresh and stop buttons are slightly different than the rest of the navbar components in that they take up the same space in the UI. When a page is loading, clicking the button will stop the navigation, hide the progress ring, and display a refresh icon. Conversely, when a page is stagnant, clicking the button will refresh the page and (in another part of the code) display a stop icon. We’ll use the refresh() and stop() methods based on the present conditions.

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

Hooking up the address bar

At a very high level, implementing the address bar appears quite simple. When a URL is entered in the textbox, pressing Enter will call the navigate() method using the address bar input value as its parameter.

However, today’s modern browsers have increased the amount of functionality for added convenience to the user. This adds some complexity to the implementation, depending on the number of scenarios you intend on accommodating.

const RE_VALIDATE_URL = /^[-:.&#+()[\]$'*;@~!,?%=\/\w]+$/;

// Attempt a function
function attempt(func) {
  try {
    return func();
  }
  catch (e) {
    return e;
  }
}

// Navigate to the specified absolute URL
function navigate(webview, url, silent) {
  let resp = attempt(() => webview.navigate(url));
  // ...
}

// Navigate to the specified location
this.navigateTo = loc => {
  // ...
  // Check if the input value contains illegal characters
  let isUrl = RE_VALIDATE_URL.test(loc);
  if (isUrl && navigate(this.webview, loc, true)) {
    return;
  }
  // ... Fallback logic (e.g. prepending http(s) to the URL, querying Bing.com, etc.)
};

// Listen for the Enter key in the address bar to navigate to the specified URL
this.urlInput.addEventListener("keypress", e => {
  if (e.keyCode === 13) {
    this.navigateTo(urlInput.value);
  }
});

Here are some example scenarios to consider. Say the value "microsoft.com" was entered into the address bar. The URL is not entirely complete. Passing that value into the navigate() method would end unsuccessfully. The browser must acknowledge that the URL is incomplete and determine whether http or https is the correct protocol to prepend. Furthermore, a URL may not have been intended as a URL at all. Say the value “seahawks” was entered into the address bar. Many browsers have their address bar double as a search box. The browser must establish that the value is not a URL, and fall back to querying a search engine for that value.

Displaying the favicon

Acquiring a favicon can be tricky, as there are several ways in which it can be displayed. The easiest route would be to check the root of the website for a file named "favicon.ico". Though, some sites are actually in the subdomain and may have a different favicon. For example, the favicon for “microsoft.com” is different than the favicon for “windows.microsoft.com”. In order to minimize the ambiguity, another route would be to check the markup of the page for a link tag within the document head with a “rel” attribute of “icon” or “shortcut icon”. We use the invokeScriptAsync() method to inject script into the WebView control, which will return a string if successful. Our script will search for all elements in the hosted page with a link tag, check if the ref attribute contains the word “icon”, and, if there is a match, return the value of the “href” attribute back to the app.

// Check if a file exists at the specified URL
function fileExists(url) {
  return new Promise(resolve =>
    Windows.Web.Http.HttpClient()
      .getAsync(new URI(url), Windows.Web.Http.HttpCompletionOption.responseHeadersRead)
      .done(e => resolve(e.isSuccessStatusCode), () => resolve(false))
  );
}

// Show the favicon if available
this.getFavicon = loc => {
  let host = new URI(loc).host;

  // Exit for cached ico location
  // ...

  let protocol = loc.split(":")[0];

  // Hide favicon when the host cannot be resolved or the protocol is not http(s)
  // ...

  loc = `${protocol}://${host}/favicon.ico`;

  // Check if there is a favicon in the root directory
  fileExists(loc).then(exists => {
    if (exists) {
      console.log(`Favicon found: ${loc}`);
      this.favicon.src = loc;
      return;
    }
    // Asynchronously check for a favicon in the web page markup
    console.log("Favicon not found in root. Checking the markup...");
    let script = "Object(Array.from(document.getElementsByTagName('link')).find(link => link.rel.includes('icon'))).href";
    let asyncOp = this.webview.invokeScriptAsync("eval", script);

    asyncOp.oncomplete = e => {
      loc = e.target.result || "";

      if (loc) {
        console.log(`Found favicon in markup: ${loc}`);
        this.favicon.src = loc;
      }
      else {
        this.hideFavicon();
      }
    };
    asyncOp.onerror = e => {
      console.error(`Unable to find favicon in markup: ${e.message}`);
    };
    asyncOp.start();
  });
};

As mentioned earlier, we are making use of the new ES2015 specification throughout our code. You may have noticed the use of arrow notation in many of the previous code samples, among other new JavaScript APIs. The injected script is a great example of the code improvement exhibited by implementing ES2015 features.

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

// After (ES6):
"Object(Array.from(document.getElementsByTagName('link')).find(link => link.rel.includes('icon'))).href"

Adding keyboard shortcuts

Unlike the features we have already covered, implementing keyboard shortcuts requires a small amount of C++ or C# code to create a Windows Runtime (WinRT) component.

Keyboard shortcuts flowchart

In order to recognize the defined hotkeys for particular actions, such as Ctrl + L to select the address bar and F11 to toggle full-screen mode, we need to inject script into the WebView control. This is done using the invokeScriptAsync() method we discussed earlier. However, we need some way to communicate the key codes back to the app layer.

With the addWebAllowedObject() method, we can expose a method for the injected script to pass the hotkeys back to our app logic in JavaScript. Although, in Windows 10, the WebView control is off-thread. We need to create a dispatcher, which will marshal the event through to the UI thread so that the app layer can receive the notification.

KeyHandler::KeyHandler()
{
	// Must run on App UI thread
	m_dispatcher = Windows::UI::Core::CoreWindow::GetForCurrentThread()->Dispatcher;
}

void KeyHandler::setKeyCombination(int keyPress)
{
	m_dispatcher->RunAsync(
		CoreDispatcherPriority::Normal,
		ref new DispatchedHandler([this, keyPress]
	{
		NotifyAppEvent(keyPress);
	}));
}
// Create the C++ Windows Runtime Component
let winRTObject = new NativeListener.KeyHandler();

// Listen for an app notification from the WinRT object
winRTObject.onnotifyappevent = e => this.handleShortcuts(e.target);

// Expose the native WinRT object on the page's global object
this.webview.addWebAllowedObject("NotifyApp", winRTObject);

// ...

// Inject fullscreen mode hot key listener into the WebView with every page load
this.webview.addEventListener("MSWebViewDOMContentLoaded", () => {
    let asyncOp = this.webview.invokeScriptAsync("eval", `
        addEventListener("keydown", e => {
            let k = e.keyCode;
            if (k === ${this.KEYS.ESC} || k === ${this.KEYS.F11} || (e.ctrlKey && k === ${this.KEYS.L})) {
                NotifyApp.setKeyCombination(k);
            }
        });
    `);
    asyncOp.onerror = e => console.error(`Unable to listen for fullscreen hot keys: ${e.message}`);
    asyncOp.start();
});

Customizing the browser

Now that we have incorporated the key WebView APIs, let’s explore how we can customize and polish our user interface.

Branding the title bar

Leveraging Windows Runtime APIs, we can use the ApplicationView.TitleBar property to modify the color palette for all components in the app title bar. In our browser, we modify the colors on app load to match the background color of the navbar. We also modify the colors when either of the menus are open to match the background color of the menu. Each color must be defined as an object of RGBA properties. For convenience, we created a helper function to generate the correct format from a hexadecimal string.

//// browser.js
// Use a proxy to workaround a WinRT issue with Object.assign
this.titleBar = new Proxy(Windows.UI.ViewManagement.ApplicationView.getForCurrentView().titleBar, {
  "get": (target, key) => target[key],
  "set": (target, key, value) => (target[key] = value, true)
});

//// title-bar.js
// Set your default colors
const BRAND = hexStrToRGBA("#3B3B3B");
const GRAY = hexStrToRGBA("#666");
const WHITE = hexStrToRGBA("#FFF");

// Set the default title bar colors
this.setDefaultAppBarColors = () => {
  Object.assign(this.titleBar, {
    "foregroundColor": BRAND,
    "backgroundColor": BRAND,

    "buttonForegroundColor": WHITE,
    "buttonBackgroundColor": BRAND,

    "buttonHoverForegroundColor": WHITE,
    "buttonHoverBackgroundColor": GRAY,

    "buttonPressedForegroundColor": BRAND,
    "buttonPressedBackgroundColor": WHITE,

    "inactiveForegroundColor": BRAND,
    "inactiveBackgroundColor": BRAND,

    "buttonInactiveForegroundColor": GRAY,
    "buttonInactiveBackgroundColor": BRAND,

    "buttonInactiveHoverForegroundColor": WHITE,
    "buttonInactiveHoverBackgroundColor": BRAND,

    "buttonPressedForegroundColor": BRAND,
    "buttonPressedBackgroundColor": BRAND
  });
};

Other functionality

The progress indicator, as well as the settings and favorites menus, leverage CSS transitions for animation. With the former menu, the temporary web data is cleared using the clearTemporaryWebDataAsync() method. With the latter menu, the list of favorites is stored on a JSON file in the root folder of the roaming app data store.

Citations

The JSBrowser logo is based on trees by Nicholas Menghini from the Noun Project.

Code of Conduct

This project has adopted the Microsoft Open Source Code of Conduct. For more information see the Code of Conduct FAQ or contact [email protected] with any additional questions or comments.

jsbrowser's People

Contributors

aarongustafson avatar alxlu avatar djdavid98 avatar dotproto avatar filiphsps avatar jaketech53 avatar jarennert avatar jayrenn avatar jdalton avatar jdc20181 avatar melanierichards avatar melwinalm avatar seksenov avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

jsbrowser's Issues

Access Violation

I'm running windows 10. VS2015 Community Edition and getting:

WWAHost.exe: 0xC0000005: Access violation reading location 0x0000004B.

WebView not downloading Picture properly

Hi, recently I also wrote on the Windows Blog regarding this issue but now I have found you on GitHub. This is my issue I have with Webview and other apps have it too:

I used WebControl on WP8.0 and now WebView on Windows 10 especially on Windows 10 Mobile and the results for my app say that WebControl renders the HTML string better then the current WebView. On WebView with Windows 10 SDK pictures get rendered wrong if used on a Windows 10 Mobile device from the first build till the last all of them have this issue because of WebView.

This is something that the team must have a look into. My app has already a lot of Windows 10 Mobile users that see this bug and the app itself can not change this. The bug is that pictures are not downloaded properly if used via NavigateToString() to an HTML string. The string is properly written and the same string gives good results on WP8.1 with WebControl. I hope you look also in this because this is frustrating. I have attached one picture as example how the picture is not downloaded properly and there is no way for me to fix it. Calling a refresh, I mean NavigateToString() again solves this issue but why does it not work on the first try?!

I wanted to attach a screenshot of this how it happens but its not working. if you want to fix this issue you can contact me under dino[dot]borogovac[at]outlook[dot]com where I can send you the screenshots as prove that something is really wrong with WebView. Thanks in advance.

README.md: HTML and CSS are not programming languages!

In README.md, this sentence bugs me and pretty much any other people reading it:

In addition to JavaScript, HTML and CSS are the other core programming languages used.

Please at least remove the "programming" word from the sentence so that it makes sense.

Running JSBrowser in IOT Core

Hello All. I have successfully loaded JSBrowser on the Windows 10 IOT core using VS. There's an issue however, input from keyboard isn't working 100%. I can't input any URL into the address bar. I can type them in, but when I hit enter it never executes. I'm working on pulling the debug down to see if there's anything that stands out. Wondering if anyone else has attempted this and succeeded?

Thanks.

Aaron

Copy and Paste Issue.

There appears to be a issue with the browser being able to copy text to the clipboard. Every time I did copied some text from websites. I would then paste it and it would just give me what I copied on my computer before I copied text from the browser. Could anybody shed some light on the issue?

Does not run on Windows 10

Is it possible to run this on the new windows 10? I get the "Error: DEP3320 : Target device's operating system version does not meet the application's minimum requirement. Minimum required operating system is Windows 10.0."

Open sourcing Edge and EdgeHTML

You guys should open source your browser, like how Firefox, Chromium, and Webkit are. I bet this would bring about contribution from the community and help the web make faster progress.

W8.1 compatible?

The readme suggests that this is to demo capabilities of W10 platform.

Can this project run as a W8.1 app by any chance? Is there any dependency on Edge itself?

Thanks for the great work.

Please Expose DOM/API in UWP

This is a pretty cool project. Good to see the extensibility of Edge. There is a problem with your implementation, however. UWP/.NET developers like coding in C#/VB.NET/F#. :) So, it would be nice to either:

  1. Expose Edge DOM in UWP: https://wpdev.uservoice.com/forums/110705-dev-platform/suggestions/9126583-webview-expose-dom-as-c-net-api
  2. Enable UWP to transpile artifacts into web-standard compliant artifacts/executables: https://wpdev.uservoice.com/forums/110705-dev-platform/suggestions/7897380-expand-enable-universal-windows-platform-to-transp

The first is more applicable to this repo, but even then I realize this is not something this repo would solve exactly. You need a chatroom/forum. :)

It would be great to start seeing more discussion (and awareness) around these issues. There is a huge divide in the MSFT developer ecosystem between web and native developers, and it incredibly costly (on many levels) to MSFT and the developers that follow it. Ultimately, this repo (or more accurately, its owners) will most definitely assist in getting this reconciled and protect MSFT investments/assets in this regard.

Thanks again for being innovative and producing this project, and for any consideration towards these issues!

Print fails

When I load an URL into the JSBrowser (or actually any <x-ms-webview>) print (via e.g. window.print() it fails with an exception in an edge dll (generated?) preview.js :(

Is there anything to work around this as the webview and therefor also this browser is only working halfway.

To test:

  1. Open JSBrowser
  2. Navigate to any page which uses window.print(), I made the simplest page possible http://cthedot.de/test/print.html
  3. click "print"
  4. nothing happens or if you have started JSBrowser from VS it shows the exception mentioned

With Edge still having no Fullscreen mode I wanted to use JSBrowser for an browser based app at work but it needs printing. So actually am very much stuck as iframes do not work either (seem to need https content in Windows 10)

Thanks!

"Deploy started..." stall in VS2015 (Community) on Win7 x64

This could be entirely specific to my setup but after installing VS2015 community edition, I can build the JSBrowser and NativeListener sub-projects but attempting to run them locally stalls at "Deploy started..." and resulting "bin" folder do not appear to contain anything executable that I can use for testing. Is there something basic/fundamental about the project setup and build requirements or setup that I'm missing here?

Many thanks in advance for any newbie help you could provide.

Color

Could you change code of this program, because number of color is not good for christians. Lets change this number to 777.
Now, I will show fragments, where is this code is use
}
#urlInput:focus {
border-color: #0078D7;
color: #666;

.effect-moveleft .outer-nav a {
color: #666;
padding: 15px;
margin: 0;
cursor: pointer;

#favMenu .url {
font-size: 12px;
color: #666;

Color

Could you change code of this program, because number of color is not good for christians. Lets change this number to 677. (There is not very much difference between 6...6 and 677). http://www.color-hex.com/color/667777
Now, I will show fragments, where is this code is use
}
#urlInput:focus {
border-color: #0078D7;
color: #666;

.effect-moveleft .outer-nav a {
color: #666;
padding: 15px;
margin: 0;
cursor: pointer;

#favMenu .url {
font-size: 12px;
color: #666;

Favicon not found

Navigating to the blog post in the JSBrowser, no favicon appears to be found.

Looking at the source code of the page, there is a favicon specified in the markup.

<link rel="shortcut icon" href="http://blogs.windows.com/msedgedev/wp-content/themes/windows-blogs/images/favicon.ico" />

favicon

Looking at the root of the subdomain, i.e. http://blogs.windows.com/favicon.ico, the URL does resolve, but no image appears.

Thus, the reason for this bug is the order of the favicon logic. Currently, we check for a favicon at the root first, then check the markup. We need to reverse this order, especially since the favicon's specified in the markup will be more reliable as a whole.

Won't work out of the box with VS2015 update 2

I have to admit this is my first try with Universal Apps and I'm really far from using Microsoft's API directly.
I've tried to compile and run the JSBrowser on my machine with latest VS2015 and SDKs,
Even after updating my SDKs I get crashes leading to the NativeListener component.
I've also got the following warning that hints where the problem is, however I don't understand much and searching for it won't give me much clues...

2>C:\Program Files (x86)\MSBuild\14.0\Microsoft.Common.targets\ImportBefore\Microsoft.Cpp.VCLibs120Universal.targets(103,5): warning MSB3842: Project "JSBrowser" depends upon SDK "Microsoft Universal CRT Debug Runtime v10.0.10586.0" which supports apps targeting "UAP 10.0". To verify whether "Microsoft Universal CRT Debug Runtime v10.0.10586.0" is compatible with "UAP 10.0.10586.0", contact the SDK author or see http://go.microsoft.com/fwlink/?LinkID=309181.

Possible new features.

@jayrenn @alxlu @seksenov @Gr8Gatsby and I have been brainstorming new features so I figured I'd share them to get feedback from a wider audience.

In no particular order:

  • For modules, destructuring, default params, classes we can use Babel to transpile
  • Show magnifying glass to indicate URL input will be a search,

    show file (?) icon to indicate URL input will be a navigation
  • Auto truncation of http: protocol from address bar
  • Extensions
  • Auto-complete, drop-down suggestion list
  • Show favicon and/or screenshot preview of favorite
    (maybe list view has favicon, grid view has screenshots)
  • URL highlighting (green for https, black for domain, dark gray for the rest)
  • Import/export favorites
  • Implement ES6 modules. Pending implementation in Edge
  • Verify TLD exists in official list
  • Use storage other than the roaming folder
  • User theming
  • Tabs
  • Inking
  • More secure solution for keyboard shortcuts. Pending component work
  • Right-click context menu
  • F12
  • Voice Command Definition file to handle navigations through Cortana

Certificate Issue

Hello team!

I want to use this approach of browser as custom browser for a client but their sites run via certificate based auth, we must implement that certifcation dialog like IE or Edges does, but dunno how can archive that and dunno the state of this project if it is viable to make something out of a demo...

Is there a plan to improve this project?
some kind of documentation to improve the "back-end" part by ourselves?

Thanks for your time!

Cannot build, missing NativeListener\NativeListener.winmd

After cloning the project and opening the solution file, clicking the Debug button (labelled "Local Machine") Gives me the following error:

Severity Code Description Project File Line
Error MSB3030 Could not copy the file "d:\Documents\Visual Studio 2015\Projects\JSBrowser\Release\NativeListener\NativeListener.winmd" because it was not found. JSBrowser C:\Program Files (x86)\MSBuild\14.0\bin\Microsoft.Common.CurrentVersion.targets 3962

How could I make this work? Running Windows 10 build 10240 with all updates installed,

How to run a asp.net core api/mvc in a packaged web app like JSBrowser ?

At first, is there somewhere a project in GitHub where we can ask questions about the Web Hosted Apps (Project Westminster) ?
My question. I want to run in the same package of the JSBrowser, a local asp.net core API/MVC
and the browser to navigate to the API localhost/port.
I don't know how to package the solution and boostrap the API before I enable the browser.
This is a common scenario for self-hosted API applications with MVC support.
Can you answer me or to guide me where to ask about ?
thanks

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.