Git Product home page Git Product logo

web-share's People

Contributors

autokagami avatar chaals avatar dbaron avatar ericwilligers avatar ewilligers avatar firien avatar foolip avatar inexorabletash avatar jpmedley avatar krinkle avatar marcoscaceres avatar mgiuca avatar miketaylr avatar plehegar avatar saschanaz avatar sidvishnoi avatar siusin avatar tomayac avatar ylafon 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

web-share's Issues

Share Images (high-level abstraction over Blob)

In #7 I proposed sharing Blobs. The primary use case for this is sharing images, but using this API to share images is a bit hard. If you wanted to share the contents of a <canvas> you would do:

var canvas;  // HTMLCanvasElement representing a <canvas> element
canvas.toBlob(blob => navigator.share({blob: blob, mimeType: 'image/png'}),
              'image/png');

A little unwieldy, but manageable.

To share an <img> element, things get a bit hairy:

var image;  // HTMLImageElement representing an <img> element
var canvas = document.createElement('canvas');
canvas.width = image.width;
canvas.height = image.height;
canvas.getContext('2d').drawImage(image, 0, 0);
canvas.toBlob(blob => navigator.share({blob: blob, mimeType: 'image/png'}),
              'image/png');

(Note: I haven't tested this code, just wrote it on the fly. There may be an easier way but that's the best way I can find to convert an image into a blob.)

So maybe we should be providing a share attribute called 'image' that takes a CanvasImageSource -- basically lets you directly share an Image, Video or Canvas object without having to convert to a blob. The usage would be:

var image;  // HTMLImageElement representing an <img> element
navigator.share({image: image, mimeType: 'image/png'}),

As shown above, this isn't strictly necessary (can be polyfilled). So it would be a policy decision whether we want to provide unnecessary-but-helpful abstractions, or whether we should save that for wrapper libraries.

canShare should be async...

Having something like:

partial interface Navigator {
  boolean canShare();
};

Would probably need to be async. The problems is:

  1. UA checks list of handlers (e.g., at launch time)
  2. user deletes app that handles type X (list out of date now).
  3. UA says, "sure, you can totally share this"!
  4. user has a bad time.

Otherwise, the UA would need to do IPC to check if there are handlers available - so basically that's a nonstarter there, or am I missing something?

Redundant statement

As the spec already declares [SecureContext] in the IDL, this doesn't need to be stated:

Due to the capabilities of the API surface, navigator.share is available only in secure contexts (such as https:// schemes).

Can't use Web Share on an Android WebView

Using WebShare returns an error: "Uncaught (in promise) DOMException: Internal error: could not connect to Web Share interface.".
The test device I'm using is running Android 7.0 and I'm using the Chrome Beta(Chrome 62) as WebView Implementation. Web Share works fine on Chrome Beta application.

Editorial: bibliography links go nowhere

E.g. "The Navigator interface is defined in [HTML].", but clicking on the "HTML" link goes nowhere. The bibliography appears to be missing.

This may be related to some kind of broken build process which is also producing some escaped HTML at the top of the document:

<p><a href="https://www.w3.org/" class="logo"> <span id=""> <img alt="W3C" src="https://www.w3.org/StyleSheets/TR/2016/logos/W3C" height="72" width="48"> </span></a></p> 

navigator.share() should throw a TypeError if all fields are omitted

The following call:

navigator.share({foo: 'xyz'})

Currently results in a successful share with no data.

It should reject with a TypeError.

Rationale: Empty shares are a bad user experience. They show up in the target application as empty strings which is confusing. There's the simple case of passing an empty dictionary to share, but we also have to consider the more plausible case of adding new fields in the future, and how sites that use the new API will interact with old UAs that don't support those new fields.

The current status quo is that if you share only new fields, you'll share nothing on an old UA.

We should offer feature detection for these new fields (see WebIDL #107) and then make it a TypeError if you fail to properly use the feature detection and only share new fields.

This is related to #47 which is about making navigator.share() equivalent to navigator.share({}). If we make this change, navigator.share() would remain a TypeError which makes me happy. I think navigator.share() being a successful share is nonsensical.

"the document's URL" is ambiguous

Consider the situation:

function declaredInWindow3() {
  window1.navigator.share.call(window2.navigator, { url });
}

Then navigate the frame containing window3 to window4, but save a reference to declaredInWindow3. Finally, from code in window5, call the saved function.

Which of these five documents does url get resolved relative to?

The proper pattern for this is to parse against

this Navigator object's relevant settings object's API base URL

in which case the answer will be window2.

Spec bug: Deal with undefined or missing url

Currently if you do navigator.share() on https://example.com/, it will share https://example.com/undefined, by my reading. (I.e. it will convert undefined to a USVString, then resolve it as a relative URL.)

If you add a default to the dictionary of url = "", it will instead share the current page URL, which seems nice.

Share blobs via a Blob URL?

There should be a way to share large blobs / files using the Web Share API.

Couple of ways to do this:

  • Add a blob or file attribute to the share data object, allowing such objects to be added directly.
  • Set the url attribute to a Blob URL to reference a blob.

The latter approach is nice because it keeps the API surface small and forces you to share just one piece of content (either a web URL or a Blob URL, but not both). This may or may not be desirable.

Add text language / direction attributes

@marcoscaceres indicated that we would need text language and direction attributes for shared text.

This seems like overkill to me, as we're essentially just sharing plain text. I'm not sure why language is required, and directionality should be inferrable from the text (in the standard way, by looking at the first strong character, and if the client really wants to override it, they can add a U+200F RLM). Do you have an example of an existing W3C standard that has out-of-band language and direction attributes for plain text?

I found the Notifications spec which has an explicit direction attribute. It seems there is a single direction that controls the entire notification UI ("auto", "ltr" or "rtl"), affecting all text fields (title, text, etc) as well as the layout of the buttons. It seems like that's useful for giving the site control over the precise layout of the notification (since the notification forms part of the site's UI). That doesn't make a lot of sense for Web Share because the sending site is not presenting any form of UI; rather it is sending text and other data to a different app. It's not clear what an explicit "ltr" or "rtl" should mean in the context of the receiving app. (For example, what is Twitter supposed to do if it receives an all-English text string with dir="rtl"?)

Extensibility of the API section could be removed

I'm not a huge fan of "Extensibility of the API" section, tbh. I don't think we should include it: The Share API is not any more special wrt extensibility than any other API. Same extensibility rules apply to platform APIs.

Feedback: sharing an image via Data URI resulted in user gesture error

The following feedback was emailed to me so passing on here:

I'm actually working on a collaborative whiteboard application. I wanted to share the drawings on the canvas as an image. I generated the image and tried to share it using such a code:

let url = canvasElement.toDataURL('image/png');

navigator.share({
title: document.title,
text: "Shared whiteboard",
url: url
}).then(() => console.log('Successful share'))
.catch(error => console.log('Error sharing:', error));

However, I got an exception:
"Error sharing: DOMException: Must be handling a user gesture to perform a share request."

I would say this was quite unexpected, because I was clicking on a button in the same way as with the sharing of a regular URL. I'm not sure why this user gesture was not accepted.
Moreover, is sharing of images in such a way supported?

Spec: URL is relative to current page and converted to absolute

Current behaviour in Chrome (intentional) that wasn't captured in the spec: the "url" field can be a relative URL, and if it is, it is converted into an absolute URL based on the current location, in the same way as relative URLs in links are.

In particular, sharing a URL of '.' shares the current page location's directory (without the final path segment); sharing a URL of '' shares the current URL.

Example is a little bit misleading still

The example states "Share successful"... but that's not quite correct. What was successful there was just the handoff of the data, but not necessarily that the sharing actually happened.... I know, I'm nit picking a bit here, but we don't want to mislead people into thinking the API is doing more than it actually does.

Migration to WebApps WG: Implementor interest?

This specification has been proposed for migration to the WebApps WG (which is expected to partly replace the WebPlat WG). For this to happen, we need expressions of interest/intent to commit from at least two implementors.

Please let us know if you plan to implement this specification, or if you can point to any publicly documented expressions of interest from implementors.

The draft WebApps charter will go to the Advisory Committee (AC) within the next two or three weeks, so quick responses may make the difference.

@chaals @marcoscaceres

Feature request: Add April Fools protection

If navigator.share is used on a web page that was written on April 1, the User Agent should display a warning to the user, with this text or similar:

"Warning: You are sharing content that may contain false information or fake news. Are you sure you want to spread this content?"

Remove canShare method?

As discussed with @marcoscaceres yesterday, the canShare method may be unnecessary.

Since it provides no actual arguments to query exactly what actions are supported, and any implementation of Web Share is likely to have at least one default action, it's likely that canShare would simply always return true in any implementation. Therefore, people would not check it and it would probably break sites if a rare implementation returned false. So we might just drop it (and sites can use the presence of navigator.share itself to detect whether sharing is supported).

On the other hand, if we are going to share more interesting types of data (like files, images, etc), there may be different sets of apps that can handle these data types, and we may want canShare to take an argument that describes the data, to see if there is an app that can handle that particular type.

Editorial: various missing links

In Bikeshed, most of this should be a simple matter of e.g. doing [=in parallel=] instead of in parallel.

Explainer q: why not a declarative solution?

(Just reading through the docs and filing issues as things come to mind... not fully formed ideas or anything, and probably already have good answers to any questions)

It would be great if the explainer could also discuss pros/cons of a declarative solution. For example:

<img src="https://example.com/cat" sharable>

Or:

<article sharable> 
</article>

And perhaps how the API could be used in conjunction with Web Components?

Don't allow the caller to distinguish different failure modes

Raised by @dbaron on the TAG review.

There is a minor privacy issue in distinguishing between "no apps are available" and "the user cancelled the share"; if only a handful of popular targets exist for a particular payload (especially if we add new share types that might have specialized handlers, e.g., for rare MIME types) then a malicious site could use navigator.share to check whether those apps are installed, based on the response string.

Also, in our current Android implementation, we are totally unable to distinguish between "no apps are available" and "the user cancelled the share". Therefore, let's just remove this provision. I won't go as far as to explicitly bar the user agent from distinguishing these, but add a note under security considerations.

Add a way to inject metrics into the shared URL

FR from Discourse: https://discourse.wicg.io/t/web-share-api-for-sharing-content-to-arbitrary-destination/1561/10

The developer wants a way to automatically insert a query parameter onto the shared URL like "utm_source=$TARGET_APP", which would identify which app the user chose to share to, so that the sending app can gather metrics about where their incoming links are coming from. For example:

  1. User is on https://example.com and clicks a Web Share button.
  2. The site calls navigator.share with `url: 'https://example.com``.
  3. Picker is shown. User chooses Facebook.
  4. API injects utm_source=facebook into the URL.
  5. User shares a post on Facebook.
  6. User's friend clicks the link from Facebook mobile app and friend's browser opens https://example.com/?utm_source=facebook.

This is a bit worrying from a privacy perspective -- the sender is not supposed to know which app the user chose to share to. But this is a lot more indirect because the sender only gets info about the shared app once the friend clicks the link in Step 6, so there's nothing to directly tie the app to the user. Will have to think on this.

This isn't something I'd want to do automatically. I'd want the sender to be able to opt in by adding a new data field to ShareData, e.g., add_target_to_url: 'utm_source'.

My final concern is that we don't have a good scheme to name the target app. I suppose if it's a Web Share Target it would be the full URL to the app's manifest scope. If it's an Android app, it would be the Android package name, etc. So we wouldn't get something as clean as "facebook"; it would be more like "com.facebook.katana" (the Android app). It's also a bit messy because it would be the name of the app the user shared to, not the name of the app the friend clicked the link in (so if the user shared to the Android app, but the friend clicked the link on the web, the utm_source would still show the Android app package name). This all seems very messy.

Improve public documentation for Web Share

We received a lot of requests from the Chrome Origin Trial for Web Share for improving the documentation.

Aside from writing a proper spec, we should get some dedicated developer docs (possibly coordinating with MDN).

Require user gesture?

Presumably navigator.share(...) will show some modal UI. Should this be gated behind a user gesture, or are there use cases where the user isn't interacting with the page and would still be able to understand why a share UI is being presented?

A consequence of requiring a user gesture would be that the API couldn't be exposed in workers.

Conditionally exposing share() is not great

Spec says:

User agents that do not support sharing SHOULD NOT expose share on the Navigator interface.

This doesn't seem great. A share target can be removed/added, etc. making this super weird if the API vanishes from one page load to the next.

What we should have a is static method a on Navigator, or just normal method even, as navigator is just a singleton:

if(await navigator.canShare()){
   await navigator.share(stuff);
}

Throws vs returning a rejected promise

In a number of places, the spec says that .share() "throws"... although exceptions are auto-wrapped, and .share()'s promise will be rejected, saying "throws" might confuse people expecting the method to actually throw.

We should consistently say that .share() will return a rejected promise instead.

Document Web Share vs. native share destination capabilities more clearly

Hi team-

Would it be possible to comment on or document how the share targets selection of the Web Share API is currently planned and what a roadmap might be for more native-like coverage?

Currently, if I use the demo via Chrome 75 on Android 9 to share an image or video file, common 3rd-party targets for these file types (e.g., Instagram, Twitter) don't show up in the share sheet. If I try to share it directly from the (native) Camera app, they do as expected.

The current wording in the spec is:

Present the user with a choice of one or more share targets, selected at the user agent's discretion. The user MUST be given the option to cancel rather than choosing any of the share targets. Wait for the user's choice.

Is the current level of discretion intended to change in future implementations? I realize this question may be better for the Chromium/Chrome team - it's a little unclear to me what is spec and what is implementation at this point.

The Web Share API (and other web app technologies introduced at I/O19) is super promising, but it's unclear how best to understand these differences and the impact they have on 'thin native app' vs. PWA design.

Thanks for considering!

Screenshot_20190628-172143
Screenshot_20190628-172052
Screenshot_20190628-173342

Specify behavior when a file type is rejected

Some user agents may wish to prevent certain file types, for example executable files, from being shared. This decision might be made on the basis of MIME type or file extension, and the platform.

For example, Blink identifies various file extensions as dangerous: download_file_types.

Some user agents may wish to prevent certain sites from sharing, for example known phishing sites.

Should script be able to detect in advance that such share attempts will fail? If so, then share should throw a TypeError and canShare should return false. If not, then share should throw a NotAllowedError (like if there was no user gesture) or AbortError (like if the user cancelled or there were no suitable share targets) and canShare should return true.

Intent to Migrate Web Share API

Intent to Migrate: Web Share API

Hi Folks working on this... with the Web Apps WG now up and running, we are ready to adopt this specification into the WG for formal standardization along the w3c rec track. πŸŽ‰

Before doing so, I could use a bit of help just filling out the template below... I've got things started already, but those with knowledge of the spec please jump in.

Working group decision to adopt

In W3C WebApps Charter

Proposal

https://github.com/WICG/web-share/

Adopt level/version 1 and 2?

Summary

An API for sharing text, links and other content to an arbitrary destination of the user's choice.

The available share targets are not specified here; they are provided by the user agent. They could, for example, be apps, websites or contacts.

Motivation and Use Cases

Described in the explainer.

Compatibility Risk

Please characterize how much we might regret standardizing this new feature were we to change or remove it in the future. If you don’t have a github repository, include in this email links to relevant discussions, or documentation about support for the feature on the Web.

As the feature is shipping in two browsers, there is risk with making too many changes to v1 of this API. However, it would be good to perform conformance/interop testing, and address any issues during the next phase of the standardization process.

Ongoing technical constraints

Discussion of options on various operating systems:
https://github.com/WICG/web-share/blob/master/docs/native.md

Not supported as a native feature across all operating systems. It is foreseeable that browsers could "share" across web apps, via the Share Target API.

Link to implementation experience and demos

Implemented in Chrome (since 61) and Safari (since 66).

Was also trialed/used on twitter.com. (still used there?)

Data

What data do you have available that indicates that this enhancement will affect many users of the Web. Quantify the fraction of websites that are currently using something similar to this feature. Or, if a new feature, characterize the reason that you expect this to be far reaching.

Security and Privacy

Outline the security and privacy implications of your proposal for end-users. Otherwise, indicate if there are none.

Accessibility

Outline the implications of your proposal relative to access by everyone regardless of disability. Otherwise, indicate if there are none.

Internationalization

See issue #6

Demos don't check for https to make error messaging less obtuse

Heads up that to get to these demos, a search for "web share api test wicg github" on Google results in a link (wicg.github.io/web-share/demos/share-files.html) with http: scheme. The distinction between http and https is somewhat hidden on mobile still as compared to current desktop browsers.

Per the docs this API only works from https:. Because I didn't realize that I hadn't loaded https, it took a while to figure out if my browser needed Android-level app permissions for this to work or there was some other failure - more diagnostic if possible while enabling bleeding edge capability is always welcome.

Thanks for considering, and looking forward to using this API!

(Curiously the demo is the only link in these search results that's still on http by default)

Screen Shot 2019-06-14 at 9 56 52 PM

Allow for share target addition in target selection step of navigator.share()

In the current spec, Section 2.1.1 step 5.1 instructs the browser "If there are no share targets available, reject p with AbortError, and abort these steps."

I'd like to propose instead that step 5.2 be expanded to allow a UI workflow for adding a new share target to use immediately. In the event a browser has no such UI and no share targets exist, only then should the promise automatically be rejected with an AbortError. This change would also negate the verbiage in Section 2.1 that instructs the browser in regards to feature detection when no share targets are available.

Separate out failure modes for "no targets available" and cancellation/transmission error

Currently the share method throws an AbortError for three distinct failure modes:

  • No share targets available.
  • User cancelled picker.
  • Error transmitting the data to the chosen target.

Lumping all three of these together (making them indistinguishable to the client) may not be sufficient. Consider an app that wants to use the following logic:

  1. Call share.
  2. If it fails before the user sees the picker (due to input error, not allowed to show a popup, or no share targets available), fall back to showing a hard-coded set of targets (like Twitter and Facebook).
  3. If it fails after the user sees the picker (due to cancellation, or error transmitting the data), do nothing. Perhaps show an error message if there was an error transmitting the data, but not if the user cancelled the picker.

It is not currently possible to distinguish these cases. It seems the most important thing to distinguish is whether it failed before or after the user saw the picker. Secondarily, we might want to distinguish user cancellation and transmission error.

Should we perhaps change to reject with a different error type in each case? Or somehow attach additional data to the rejection object.

PSA: added index.html

Just as heads up that the W3C's automated IPR system added "index.html" to the root of the repo... it also added some other small files that it needs + a web hook.

"Share successful" - define more

I may have missed this, but what counts as a "Share successful"?

  1. If I click "Share", "Email", write some text, "Discard", does that count?
  2. If so, at which point is the successful share message fired?

How about "Failure"?

Has the ramifications of this been thought through for user privacy / control (for want of a better word) - what happens if a website insists you share something before allowing you access to a resource?

navigator.share's argument needs to be optional because ShareData has no required members

This is another thing that's a bit surprising in Web IDL, but if a dictionary has no required members, then when used as an argument type, that argument must be optional. It's this bit from https://heycam.github.io/webidl/#idl-operations:

If the type of an argument is a dictionary type or a union type that has a dictionary as one of its flattened member types, and that dictionary type and its ancestors have no required members, and the argument is either the final argument or is followed only by optional arguments, then the argument must be specified as optional. Such arguments are always considered to have a default value of an empty dictionary, unless otherwise specified.

The reason is that with no required arguments, navigator.share({}) still works, and then it looks "silly" to require the empty object.

demo code fails to parse in some browsers

The demo code fails to parse in some browsers, leading the entire javascript file to be rejected. Specifically, at https://developers.google.com/web/updates/2016/10/navigator-share, the phrase:

.then(() => console.log('Successful share')) .catch(error => console.log('Error sharing:', error))

Similar code is also used in demos/share.html and also fails to parse.

It fails in Konqueror 4.14.2 (Debian stable (Jessie 8)). I believe (based on access logs for users who reported problems) it also fails in:

"Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko"

"Mozilla/5.0 (iPhone; CPU iPhone OS 9_3_4 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Version/9.0 Mobile/13G35 Safari/601.1"

Maybe TypeError is better....?

Bit of a nit... but for .share() steps, it says:

Activate the chosen share target, convert data to a format suitable for ingestion into the target, and transmit the converted data to the target. If an error occurs starting the target or transmitting the data, reject p with AbortError, and abort these steps.

That might be better classed as TypeError there, as it's the data that caused the error. I guess the message of the AbortError could still say that... Feel free to ignore.

Offline support

Hiya! This is a pretty complicated ask, but I'd like to see offline support added to enrich this great capability.

From within a user-agent, if an origin has a foreign-fetch worker installed, other origins can- even while offline- issue requests and the foreign fetch handler has an opportunity to serve that request.

It would be very interesting and powerful if the user-agent could externalize this servicing: when a "Gallery" application goes to open a photo url, if the OS could proxy that request through the user-agent such the user agent could try to use it's foreign-fetch handler, then it could be possible for Gallery to open a photo even though the device is disconnected.

Also, without some kind of integration with foreign fetch, the Gallery app will always have to redownload the image, even though the user agent may have it cached, & that could be a considerably large download.

Move UI note to Sec/Priv section

The note that states:

always shows some form of UI, to give the user a choice of application...

Would probably better to move that to the Security and privacy considerations. Also, the language there seems to overstep a bit into making hard UI requirements.

I suggest softening the language a bit, and make recommendations instead.

Don't allow the target to decline a share

The current spec has a provision for the target to "decline to receive the data". Despite this, neither the existing Android implementation on Chrome nor the proposed Web Share Target URL-template-based API would allow the target to respond with a failure state.

Given that we aren't likely to make use of this in the near future, and that it could be re-added in a backwards-compatible way if we wanted to introduce a new failure mode, let's just remove this text from the spec for now.

Redundant notes

The two notes in the "ShareData dictionary" section are really not needed (the one about USVString, and the one about url possibly being relative). I'd suggest dropping them.

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.