Git Product home page Git Product logo

salvadordf / webview4delphi Goto Github PK

View Code? Open in Web Editor NEW
247.0 31.0 53.0 28.66 MB

WebView4Delphi is an open source project created by Salvador Díaz Fau to embed Chromium-based browsers in applications made with Delphi or Lazarus/FPC for Windows.

Home Page: https://www.briskbard.com/forum/

License: MIT License

HTML 0.61% Batchfile 0.03% Pascal 99.33% JavaScript 0.01% C++ 0.02%
windows delphi lazarus fpc pascal browser v8 webkit webview2 chromium freepascal blink vcl firemonkey fmx embarcadero delphinuspackage edge

webview4delphi's Introduction

WebView4Delphi Tweet

WebView4Delphi is an open source project created by Salvador Díaz Fau to embed Chromium-based browsers in applications made with Delphi or Lazarus/FPC.

WebView4Delphi only supports Windows. If you need to embed a web browser in Linux, Windows or MacOS consider using CEF4Delphi instead.

WebView4Delphi uses the Microsoft Edge WebView2 Runtime and Microsoft.Web.WebView2 NuGet package version 1.0.2478.35 to embed a web browser.

WebView4Delphi was developed and tested on Delphi 12.1, Delphi XE2, Delphi 7 and Lazarus 3.2/FPC 3.2.2. Delphi 6 support needs to be tested and it requires installing the second Delphi 6 patch.

WebView4Delphi includes VCL, FireMonkey (FMX) and Lazarus components.

Links

Support

If you find this project useful, please consider making a donation.

paypal

You can also support this project with Patreon.

Patreon donate button

You can also support this project with Liberapay.

Donate using Liberapay

Related projects

Other resources

Attribution

Additional: Delphinus-Support

webview4delphi's People

Contributors

hhonisch avatar jonjbar avatar michaliskambi avatar salvadordf 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

webview4delphi's Issues

Define for D2010 fix

Please, change

procedure OutputDebugMessage(const aMessage : string);
begin
  {$IFDEF DEBUG}
  OutputDebugString({$IFNDEF DELPHI16_UP}PAnsiChar{$ELSE}PWideChar{$ENDIF}(aMessage + #0));
  {$ENDIF}
end;

to

procedure OutputDebugMessage(const aMessage : string);
begin
  {$IFDEF DEBUG}
  OutputDebugString({$IFNDEF DELPHI14_UP}PAnsiChar{$ELSE}PWideChar{$ENDIF}(aMessage + #0));
  {$ENDIF}
end;

in file uWVMiscFunctions ?

Clarify in the documentation which operating systems are supported

The documentation talks about chromium, so it seems reasonable to assume OSX / Linux are supported, but the details are all windows/edge based. So it would be good to clear about which OSs are known to be supported, which are known not to be possible, and which are possible

Unsupported WebView2Loader.dll version!

Compiled the tabsheetbrowser demo, using Lazarus 2.2 64-bit, running on Windows 11 Version 22H2.
The supported WebView2Loader.dll version was the one that was included in this repository. Am I missing something? The readme file stated that if Windows 10/11 we already have the green version.

Add MacOS support

MacOS support in WebView2 is being tracked here.

WebView4Delphi will support MacOS as soon as WebView2 works on that platform.

Tabbed Browser Demo: PixelsPerInch?

Hello,

I got the exception "Property PixelsPerInch does not exists" when run the Tabbed Browser Demo.
It's when create the BrowserFrame.
I use Delphi 10.1 Berlin.

How to fix that?

how to get ajax response content?

procedure TMiniBrowserFrm.WVBrowser1AfterCreated(Sender: TObject);
begin
// We need to a filter to enable the TWVBrowser.OnWebResourceRequested event
WVBrowser1.AddWebResourceRequestedFilter('*', COREWEBVIEW2_WEB_RESOURCE_CONTEXT_ALL);

end;
procedure TMiniBrowserFrm.WVBrowser1WebResourceResponseReceived(
Sender: TObject; const aWebView: ICoreWebView2;
const aArgs: ICoreWebView2WebResourceResponseReceivedEventArgs);
var
TempArgs : TCoreWebView2WebResourceResponseReceivedEventArgs;
TempResponse : TCoreWebView2WebResourceResponseView;
uriP: PWideChar;
uri: string;
begin
TempArgs := TCoreWebView2WebResourceResponseReceivedEventArgs.Create(aArgs);
TempResponse := TCoreWebView2WebResourceResponseView.Create(TempArgs.Response);
TempArgs.Request.Get_uri(uriP);
uri := uriP;
if not uri.Contains('getrealposlist') then Exit;
Memo1.Lines.Add( DateTimeToStr(Now)+ ':' + uriP);
//TempResponse.GetContent();

end;

WVBrowser1WebResourceResponseViewGetContentCompleted event not emited.

Caret disappears in FMXTabbedBrowser

The caret in the address box disappears when the user changes the active tab.
The address box has the focus and the user can type but there's no caret.
If the user shows the system menu then the caret shows again.

Bug in Lazarus regarding the "ContextMenuRequested" event

Hello.
I encountered an issue using the custom right-click menu callback event "ContextMenuRequested" in Lazarus.
When setting the menu item to select an event proxy object, it causes the browser object (WVBrowser1) address to become invalid.
critical code:
Current browser object:
TempMenuItem.AddCustomItemSelectedEvent(WVBrowser1);

Temporary copy:
TempMenuItem.AddCustomItemSelectedEvent(WVBrowser2);

Operation steps:
After the program runs.

  1. In the browser window, right-click the mouse and the menu will pop up correctly. Execute correctly.
  2. Click on the window (TButton) to trigger an event. Execute correctly. (Switchable window, uncertain when this issue will occur)
  3. In the browser window, right-click the mouse and it does not execute correctly. The window appears unresponsive and freezes.

The reproduction method of this problem can be repeatedly found by right clicking on the browser window, clicking a button, or switching windows

The current temporary solution is to create another TWVBrowser object and only handle the Custom Item Selected event.

Code change from CookieManager example

procedure TMainForm.WVBrowser1ContextMenuRequested(Sender: TObject; const aWebView: ICoreWebView2; const aArgs: ICoreWebView2ContextMenuRequestedEventArgs);
var
  TempArgs: TCoreWebView2ContextMenuRequestedEventArgs;
  TempCollection: TCoreWebView2ContextMenuItemCollection;
  TempMenuItemItf: ICoreWebView2ContextMenuItem;
  TempMenuItem: TCoreWebView2ContextMenuItem;
begin
  TempArgs := TCoreWebView2ContextMenuRequestedEventArgs.Create(aArgs);
  TempCollection := TCoreWebView2ContextMenuItemCollection.Create(TempArgs.MenuItems);
  TempMenuItem := nil;

  try
    TempCollection.RemoveAllMenuItems;

    if WVBrowser1.CoreWebView2Environment.CreateContextMenuItem('Exit', nil, COREWEBVIEW2_CONTEXT_MENU_ITEM_KIND_COMMAND, TempMenuItemItf) then
    try
      TempMenuItem := TCoreWebView2ContextMenuItem.Create(TempMenuItemItf);
      FExitCommandID := TempMenuItem.CommandId;
      TempMenuItem.AddCustomItemSelectedEvent(WVBrowser1);// Replace temporary resolution code here
      TempCollection.InsertValueAtIndex(0, TempMenuItemItf);
    finally
      FreeAndNil(TempMenuItem);
    end;
  finally
    FreeAndNil(TempCollection);
    FreeAndNil(TempArgs);
  end;
end;
procedure TMainForm.WVBrowser1CustomItemSelected(Sender: TObject; const aMenuItem: ICoreWebView2ContextMenuItem);
var
  TempMenuItem: TCoreWebView2ContextMenuItem;
begin
  TempMenuItem := TCoreWebView2ContextMenuItem.Create(aMenuItem);

  if (TempMenuItem.CommandId = FExitCommandID) then
    PostMessage(Handle, WM_CLOSE, 0, 0);
  FreeAndNil(TempMenuItem);
end;

First run display window:
window_1

No feedback from the window after right clicking:
window_2

The window is stuck:
window_3

Parameter OleVariant type in dynamic link library

@salvadordf
Hello, I am the author of the energy open source framework and previously wrapped a set of underlying libraries in Golang using Lazarus CEF4Delphi.
Now I have also used Golang to encapsulate a complete set of dynamic link libraries based on Lazarus WebView4Delphi.
I have a question, I in the class: "TWVBrowserBase, TCoreWebView2," function "AddHostObjectToScript, AddHostObjectToScriptWithOrigins"
The parameter "object_: OleVariant" in these functions.
At this point I am not familiar with the "OleVariant" type and do not know how to use such a parameter passed in a dynamic library.
Can you give me some suggestions for reference?
I call this dynamic library API in Golang.
Can I create a generic class wrapper "OleVariant "type in Lazarus to use? Can you give me some hints.

Thank you very much.

Is there any way use the AddHostObjectToScript in Lazarus?

this line can run in delphi well,but in Lazarus, it crashed, it seems can't call TAutoObjectFactory.Create in the EXE project?
TAutoObjectFactory.Create(ComServer, TMainHostObject, Class_SampleHostObjectClass,
ciMultiInstance, tmApartment);

Delphi can't find ToolsAPI.pas or designide.dcp

Some Delphi installations seem to have problems locating the ToolsAPI.pas unit or the designide.dcp file and it's not possible to build the project.

Delphi should have the following files and directories :

  • C:\Program Files (x86)\Embarcadero\Studio\ xx.xx \source\ToolsAPI : ToolsAPI.pas should be in this directory.
  • C:\Program Files (x86)\Embarcadero\Studio\ xx.xx \lib\win32\release : designide.dcp should be in this directory.

Delphi should have this entry in the library path for Windows 32-bit :
$(BDSLIB)\$(Platform)\release

The browsing path should have this entry for Windows 32-bit and Windows 64-bit :
$(BDS)\source\ToolsAPI

Got stuck after CreateBrowser: No invoke of ControllerCompleted

On initialization of my DLL create the GlobalWebView2Loader and start it.
Now I want to make some forms that should show the content of an URL. I did it like your SimpleBrowser example. When I open it and wait, eveything goes fine. When I move it during of creating/navigate the process stucks and no event (ControllerCompleted nor AfterCreated) got invoked. Now nothing helps excepts restarting the whole application.
When I open one form und then open an other form and move the first one over the second one while the second one is waiting on the next event after CreatingBrowser the process got stuck. Nothing helps excepts restarting the whole application...
Sometime I got the InitializationError: The parent windows was destroyes before the controller creation was finished. What should I do when the forms closes und the creation was not finished?

Do you know what I'm doing wrong or are that limitations of the WebView2?

Pixel per inch

Screenshot - 14_10_2022 , 11_14_24
D10.2.3
On the tabbed Demo no pixel per inch for my Delphi
I took off the property by hand from DFM's

Furthermore on windowlessbrowser demo
on line 237 WVBrowser1.CreateWindowlessBrowser(FWVDirectCompositionHost.Handle)
and

Result := CreateWindowlessBrowser(aHandle, GlobalWebView2Loader.Environment)
I traced it to this point Result := FCoreWebView2Environment.BaseIntf

Separate RunTime package into One for FMX and one for VCL

I recently made use of your project to replace the TWebBrowser with the Edge engine. Thank you for open sourcing this project.

When it came time to deploying, I discovered that despite the fact that my application is for the VCL, I now need to deploy the FMX BPL (~12Mb) because the run-time package includes the FMX browser and related classes. I have removed those references and compiled a different run-time package, but as a result, it makes it hard to manage your repo as a Git sub-module and keep everything up to date.

Would you please separate the run-time package into one for the VCL and one for FMX and have the Design-time package use both of them?

Delphi 7 Support

I was wondering if it would be not too hard to make this project compatible with Delphi 7 ?

Download files such as xls, PDF, CSV, etc

Dear salvadordf,Sorry to bother you again, but it seems that I cannot receive activation emails after registering in forum 'briskbard.com'.

When I click on a webpage button, it triggers the submit event,then a .csv file will be directly opened in the pop-up ChildForm. However, I hope to implement downloading the file instead of directly opening it in the browser. How can I modify the code to achieve the desired result?
Thank you!!!

Issue when change parent of form

Hello,

if you change the parent of the form that hosts the WVBroser, you go to create an inconsistency in the CoreWebView2Controller interface which is invisible and without parent.

i also tried re-assigning the parentWindow and resetting the visibility but it doesn't work.

I think it's a Microsoft bug, do you know any workarounds?

you can easily reproduce the problem through the tabbedBrowser demo unit that I modified and attached

best regards
TabbedBrowserChange.zip

Get html

Hi.
How to get html source code?

When I run and terminated my application on debug mode, the application has leaked memory of TCoreWebView2Profile. (WebView4Delphi-1.0.2420.47)

I use WebView4Delphi VCL.

When I run and terminated my application on debug mode, the application has leaked memory.

Memory leak description follows:

--------------------------------2024/4/23 12:47:46--------------------------------
A memory block has been leaked. The size is: 52

This block was allocated by thread 0x6B28, and the stack trace (return addresses) at the time was:
63727E [System.pas][System][@getmem$qqri][4949]
638B43 [System.pas][System][TObject.NewInstance][18306]
639242 [System.pas][System][@ClassCreate$qqrpvzc][19635]
88D0EA [uWVCoreWebView2Profile.pas][uWVCoreWebView2Profile][TCoreWebView2Profile.Create]
8874E1 [uWVCoreWebView2.pas][uWVCoreWebView2][TCoreWebView2.GetProfile][2344]
895A45 [uWVBrowserBase.pas][uWVBrowserBase][TWVBrowserBase.ControllerCompletedHandler_Invoke][4073]
872437 [uWVCoreWebView2Delegates.pas][uWVCoreWebView2Delegates][TCoreWebView2CreateCoreWebView2ControllerCompletedHandler.Invoke][1570]
679E2BC3 [Unknown function at ??0IDataFieldVisitor@telemetry_client@@QAE@ABV01@@z]
679D8EEF [Unknown function at ??0IDataFieldVisitor@telemetry_client@@QAE@ABV01@@z]
679DF454 [Unknown function at ??0IDataFieldVisitor@telemetry_client@@QAE@ABV01@@z]
6798B2E5 [Unknown function at OQS_SIG_verify]

The block is currently used for an object of class: TCoreWebView2Profile

The allocation number is: 8394

Current memory dump of 256 bytes starting at pointer address 7F36B7C0:
38 C9 88 00 00 C5 82 31 00 C5 82 31 00 C5 82 31 00 C5 82 31 00 C5 82 31 00 C5 82 31 00 C5 82 31
00 C5 82 31 14 00 00 00 00 00 00 00 00 00 00 00 5D CF 06 7A 80 80 80 80 00 00 00 00 41 C6 36 7F
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 B8 1C 00 00 ED 72 63 00 CB DC 63 00 9E 57 6B 00
83 5A 72 00 C3 5D 6B 00 80 F8 69 00 F3 F9 69 00 D7 FA 69 00 B7 D8 69 00 25 51 6B 00 D0 D8 69 00
28 6B 00 00 28 6B 00 00 9A 72 63 00 8C DF 63 00 18 C4 63 00 94 D8 64 00 A9 D8 64 00 25 8D 63 00
5A 8B 63 00 8D 92 63 00 F0 D4 69 00 57 8C 63 00 ED 83 6B 00 28 00 00 00 00 00 00 00 7D 52 1D 88
90 EC BB 00 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80
80 80 80 80 80 80 80 80 82 AD E2 77 80 80 80 80 80 80 80 80 80 80 80 80 00 00 00 00 81 86 36 7F
8 . . 1 . 1 . 1 . 1 . 1 . 1 . 1
. 1 . . . . . . . . . . . . ] . z . . . . A 6 �
. . . . . . . . . . . . . . . . . . . r c . c . W k .
Z r . ] k . i . i . i . i . % Q k . i .
( k . . ( k . . r c . c . . c . d . d . % c .
Z c . c . i . W c . k . ( . . . . . . . } R .
.
w . . . . 6 �

--------------------------------2024/4/23 12:47:46--------------------------------
This application has leaked memory. The small block leaks are (excluding expected leaks registered by pointer):

37 - 52 bytes: TCoreWebView2Profile x 1

Note: Memory leak detail is logged to a text file in the same folder as this application. To disable this memory leak check, undefine "EnableMemoryLeakReporting".

XE4 compilation errors

As requested in a FB thread, some initial XE4 compilation error reports:

  • UnixToDateTime takes only one parameter and doesn't support the AReturnUTC parameter in XE4.
  • ISO8601ToDate was not introduced since XE6.

I'll report more once once I can get these fixed.

Interact with html page

How do I interact with the web page?
Can you make a demo?
I have a page with a button
put some text pressing the button get response

Acceleration Keys are not handled

"OnAccelerationKeyPressed" event doesn't trigger when Search dialog window (Ctrl+F) was activated. Can i handle all acceleration keys except Ctrl+F?

Nothing is visible, no rendering!?

Hi,

I used the code of SimpleBrowser Demo (runs fine) and expand to a kind of SimpleTabbedBrowser (because the TabbedBrowser Demo is much complicate for my little project - I only need the view...).

But now nothing is rendering.

What's wrong?

TestWebView.zip

Consider synchronous capture preview method

Would you consider a synchronous capture method (as well as a synchronous script execution too) ? This could be done by introducing a TEvent and a timeout in a method which could be named TWVBrowserBase.CapturePreviewSync.
Let me know if you need some code to illustrate this request.

Get response content

I found probably a problem in MiniBrowser demo.

In the WVBrowser1WebResourceResponseViewGetContentCompleted procedure,
there is this line
TempOLEStream.Read(FResourceContents, TempOLEStream.Size);

This give me access violation. It should not read but write content.

(btw. thanks for Delphi 7 support)

Useful functions

Hello,

Thanks for your work. You are amazing.

please add some useful function:

SelectAll

  WVBrowser1.CoreWebView2.BaseIntf.ExecuteScript('this.document.execCommand("SelectAll", true);',ICoreWebView2ExecuteScriptCompletedHandler(
    function (errorCode: HResult; resultObjectAsJson: PWideChar): HResult stdcall
    begin
      Result := S_OK;
    end))

CopySelected

WVBrowser1.CoreWebView2.BaseIntf.ExecuteScript('this.document.execCommand("copy");',ICoreWebView2ExecuteScriptCompletedHandler(
  function (errorCode: HResult; resultObjectAsJson: PWideChar): HResult stdcall
  begin
    Result := S_OK;
  end))

ClearSelection

    WVBrowser1.CoreWebView2.BaseIntf.ExecuteScript('window.getSelection().removeAllRanges();',
              ICoreWebView2ExecuteScriptCompletedHandler(
      function (errorCode: HResult; resultObjectAsJson: PWideChar): HResult stdcall
      begin
        Result := S_OK;
      end));

FindText

Procedure FindText(Const aText:String;aCaseSensitive, aBackwards, aWrapAround,
            aWholeWord, aSearchInFrames:Boolean);
begin
   if not WVBrowser1.Initialized then exit;
  
   WVBrowser1.CoreWebView2.BaseIntf.ExecuteScript(PWideChar(Format('window.find("%s",%s,%s,%s,%s,%s,false)',[
                    aText,
                    BoolToStr(aCaseSensitive,true).ToLower,
                    BoolToStr(aBackwards,true).ToLower,
                    BoolToStr(aWrapAround,true).ToLower,
                    BoolToStr(aWholeWord,true).ToLower,
                    BoolToStr(aSearchInFrames,true).ToLower
                    ])),
              ICoreWebView2ExecuteScriptCompletedHandler(
      function (errorCode: HResult; resultObjectAsJson: PWideChar): HResult stdcall
      begin
        Result := S_OK;
      end));

this function is call by event onFind of standard TFindDialog

procedure TFormBrowserEDGE.FindDialog1Find(Sender: TObject);
begin
  inherited;
  FindText(FindDialog1.FindText,
    frMatchCase in FindDialog1.Options,
    not (frDown in FindDialog1.Options),
    true,//??
    frWholeWord  in FindDialog1.Options,
    True//??
    )
end;

SaveToFile

Get HTML Source and SaveToFile

end;

Best regards
Alessandro Mancini

Add Linux support

Linux support in WebView2 is being tracked here.

WebView4Delphi will support Linux as soon as WebView2 works on that platform.

about DefaultScriptDialogsEnabled

如果不设置DefaultScriptDialogsEnabled:=false,OnScriptDialogOpening事件似乎不起作用,但是在uWVBrowser中没有这个属性,是否需要单独加上这个属性?谢谢!

console.log

Hi, this is a great job you did! Is there a way to capture the console.log in a similar way to CEF4Delphi? Thank you.

Parenting / Handle Issues

I'm working on a Delphi legacy project that's in Delphi 2005. We want to move to web which would work much better than the client server application we're currently only. Long story short, we're wanting to create a form with an embedded browser that we can use as were replace different parts of the application. So I am not sure if this issue is specific to Delphi 2005 or not.

If I put a TWVBrowser on a form and hook it up to a TWVWindowParent on a Form. I do all the initialization etc. Anyhow I'm able to pull up web pages no problem.

The problem comes with ShowModal. Ideally I start the navigation then call show modal so there is a little less evident delay loading the page. If I use Form.Show this all works great, however when I use ShowModal which I often will need to do, The handles are all released and new handles are issued. The actual browsers parent becomes invalid. I've looked for a way to reassign the parent but haven't had much luck. Is there a way to reassign the parent in the event that the handle for the TWVWindowParent is release and renewed? Let me know if you want a demo project.

Drawback or bug?

If you write a site just xxxxx.com it does not do anything
I have to add HTTP:// not like chrome and others

How to get the url in iframe?

code:
WVBrowser1.AddWebResourceRequestedFilterWithRequestSourceKinds('', COREWEBVIEW2_WEB_RESOURCE_CONTEXT_IMAGE, COREWEBVIEW2_WEB_RESOURCE_REQUEST_SOURCE_KINDS_ALL);
WVBrowser1.AddWebResourceRequestedFilterWithRequestSourceKinds('
', COREWEBVIEW2_WEB_RESOURCE_CONTEXT_MEDIA, COREWEBVIEW2_WEB_RESOURCE_REQUEST_SOURCE_KINDS_ALL);
but WebResourceRequested event can not get the url if this url open in iframe,why?

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.