From ffd300ebfd13343f7396b63b225ec2240630108c Mon Sep 17 00:00:00 2001 From: Anthony van Winkle Date: Mon, 11 Apr 2022 19:36:34 -0700 Subject: [PATCH] [fix] Linking.openURL supports 'target' value Close #2277 --- packages/docs/src/pages/docs/apis/linking.md | 4 +- .../exports/Linking/__tests__/index-test.js | 37 +++++++++++++++++++ .../src/exports/Linking/index.js | 14 ++++--- 3 files changed, 48 insertions(+), 7 deletions(-) create mode 100644 packages/react-native-web/src/exports/Linking/__tests__/index-test.js diff --git a/packages/docs/src/pages/docs/apis/linking.md b/packages/docs/src/pages/docs/apis/linking.md index 492ed6d0..de82754d 100644 --- a/packages/docs/src/pages/docs/apis/linking.md +++ b/packages/docs/src/pages/docs/apis/linking.md @@ -31,8 +31,8 @@ Returns a `Promise` that resolves to a boolean indicating whether the app can op Returns a `Promise` that resolves to the string of the URL that initially loaded the app. {% endcall %} -{% call macro.prop('openURL', '(url) => Promise<>') %} -Try to open the given url in a secure fashion. The method returns a Promise object. If the url opens, the promise is resolved. If not, the promise is rejected. +{% call macro.prop('openURL', '(url, target) => Promise<>') %} +Try to open the given url in a secure fashion. The provided target (including `undefined`) will be passed as the window target, or "_blank" if no target included. The method returns a Promise object. If the url opens, the promise is resolved. If not, the promise is rejected. {% endcall %} --- diff --git a/packages/react-native-web/src/exports/Linking/__tests__/index-test.js b/packages/react-native-web/src/exports/Linking/__tests__/index-test.js new file mode 100644 index 00000000..acc365af --- /dev/null +++ b/packages/react-native-web/src/exports/Linking/__tests__/index-test.js @@ -0,0 +1,37 @@ +/* eslint-env jasmine, jest */ + +import Linking from '..'; + +describe('apis/Linking', () => { + describe('openURL', () => { + test('calls open with a url and target', (done) => { + jest.spyOn(window, 'open').mockImplementationOnce((url, target, opener) => { + expect(url).toBe('http://foo.com/'); + expect(target).toBe('target_name'); + expect(opener).toBe('noopener'); + done(); + }); + Linking.openURL('http://foo.com', 'target_name'); + }); + + test('defaults target to _blank if not provided', (done) => { + jest.spyOn(window, 'open').mockImplementationOnce((url, target, opener) => { + expect(url).toBe('http://foo.com/'); + expect(target).toBe('_blank'); + expect(opener).toBe('noopener'); + done(); + }); + Linking.openURL('http://foo.com'); + }); + + test('accepts undefined as a target', (done) => { + jest.spyOn(window, 'open').mockImplementationOnce((url, target, opener) => { + expect(url).toBe('http://foo.com/'); + expect(target).toBe(undefined); + expect(opener).toBe('noopener'); + done(); + }); + Linking.openURL('http://foo.com', undefined); + }); + }); +}); diff --git a/packages/react-native-web/src/exports/Linking/index.js b/packages/react-native-web/src/exports/Linking/index.js index aece97fb..6d6fe3c1 100644 --- a/packages/react-native-web/src/exports/Linking/index.js +++ b/packages/react-native-web/src/exports/Linking/index.js @@ -67,12 +67,16 @@ class Linking { /** * Try to open the given url in a secure fashion. The method returns a Promise object. + * If a target is passed (including undefined) that target will be used, otherwise '_blank'. * If the url opens, the promise is resolved. If not, the promise is rejected. - * Dispatches the `onOpen` event if `url` is opened successfully + * Dispatches the `onOpen` event if `url` is opened successfully. */ - openURL(url: string): Promise { + openURL(url: string, target?: string): Promise { + if (arguments.length === 1) { + target = '_blank'; + } try { - open(url); + open(url, target); this._dispatchEvent('onOpen', url); return Promise.resolve(); } catch (e) { @@ -86,13 +90,13 @@ class Linking { } } -const open = (url) => { +const open = (url, target) => { if (canUseDOM) { const urlToOpen = new URL(url, window.location).toString(); if (urlToOpen.indexOf('tel:') === 0) { window.location = urlToOpen; } else { - window.open(urlToOpen, '_blank', 'noopener'); + window.open(urlToOpen, target, 'noopener'); } } };