From ca3720511765cd2e2e4474619979275cfc2529d0 Mon Sep 17 00:00:00 2001 From: Lorenzo Natali Date: Tue, 18 Apr 2017 10:07:16 +0200 Subject: [PATCH] Fix #1728. Generalized Share embedded strings. More tests (#1729) --- web/client/components/share/SharePanel.jsx | 44 ++++++++++++++----- .../share/__tests__/ShareEmbed-test.jsx | 16 +++++++ .../share/__tests__/SharePanel-test.jsx | 7 +++ web/client/plugins/Share.jsx | 31 ++++++------- 4 files changed, 71 insertions(+), 27 deletions(-) diff --git a/web/client/components/share/SharePanel.jsx b/web/client/components/share/SharePanel.jsx index 764ebd46d0..e9040da3fa 100644 --- a/web/client/components/share/SharePanel.jsx +++ b/web/client/components/share/SharePanel.jsx @@ -1,4 +1,4 @@ -/** +/* * Copyright 2016, GeoSolutions Sas. * All rights reserved. * @@ -6,13 +6,6 @@ * LICENSE file in the root directory of this source tree. */ - /** DESCRIPTION - * SharePanel allow to share the current map in some different ways. - * You can share it on socials networks(facebook,twitter,google+,linkedin) - * copying the direct link - * copying the embedded code - * using the QR code with mobile apps - */ const React = require('react'); const Dialog = require('../misc/Dialog'); @@ -24,13 +17,32 @@ const ShareQRCode = require('./ShareQRCode'); const {Glyphicon, Tabs, Tab} = require('react-bootstrap'); const Message = require('../../components/I18N/Message'); + /** + * SharePanel allow to share the current map in some different ways. + * You can share it on socials networks(facebook,twitter,google+,linkedin) + * copying the direct link + * copying the embedded code + * using the QR code with mobile apps + * @class + * @memberof components.share + * @prop {boolean} [isVisible] display or hide + * @prop {node} [title] the title of the page + * @prop {string} [shareUrl] the url to use for share. by default location.href + * @prop {string} [shareUrlRegex] reqular expression to parse the shareUrl to generate the final url, using shareUrlReplaceString + * @prop {string} [shareUrlReplaceString] expression to be replaced by groups of the shareUrlRegex to get the final shareUrl to use for the iframe + * @prop {string} [shareApiUrl] url for share API part + * @prop {string} [shareConfigUrl] the url of the config to use for shareAPI + * @prop {function} [onClose] function to call on close window event. + * @prop {getCount} [getCount] function used to get the count for social links. + */ let SharePanel = React.createClass({ propTypes: { isVisible: React.PropTypes.bool, title: React.PropTypes.node, shareUrl: React.PropTypes.string, - shareEmbeddedUrl: React.PropTypes.string, + shareUrlRegex: React.PropTypes.string, + shareUrlReplaceString: React.PropTypes.string, shareApiUrl: React.PropTypes.string, shareConfigUrl: React.PropTypes.string, onClose: React.PropTypes.func, @@ -41,14 +53,26 @@ let SharePanel = React.createClass({ return { title: , onClose: () => {}, + shareUrlRegex: "(h[^#]*)#\\/viewer\\/([^\\/]*)\\/([A-Za-z0-9]*)", + shareUrlReplaceString: "$1embedded.html#/$3", closeGlyph: "1-close" }; }, + generateUrl(orig = location.href, pattern, replaceString) { + let regexp = new RegExp(pattern); + if (orig.match(regexp)) { + return orig.replace(regexp, replaceString); + } + return orig; + }, render() { // ************************ CHANGE URL PARAMATER FOR EMBED CODE **************************** /* if the property shareUrl is not defined it takes the url from location.href */ const shareUrl = this.props.shareUrl || location.href; - const shareEmbeddedUrl = this.props.shareEmbeddedUrl || this.props.shareUrl || location.href; + let shareEmbeddedUrl = this.props.shareUrl || location.href; + if (this.props.shareUrlRegex && this.props.shareUrlReplaceString) { + shareEmbeddedUrl = this.generateUrl(shareEmbeddedUrl, this.props.shareUrlRegex, this.props.shareUrlReplaceString); + } const shareApiUrl = this.props.shareApiUrl || this.props.shareUrl || location.href; const social = ; const direct = (
); diff --git a/web/client/components/share/__tests__/ShareEmbed-test.jsx b/web/client/components/share/__tests__/ShareEmbed-test.jsx index 5286dcdc2b..b719ddee94 100644 --- a/web/client/components/share/__tests__/ShareEmbed-test.jsx +++ b/web/client/components/share/__tests__/ShareEmbed-test.jsx @@ -10,6 +10,7 @@ const expect = require('expect'); const React = require('react'); const ReactDOM = require('react-dom'); const ShareEmbed = require('../ShareEmbed'); +const {head} = require('lodash'); const ReactTestUtils = require('react-addons-test-utils'); describe("The ShareEmbed component", () => { @@ -41,5 +42,20 @@ describe("The ShareEmbed component", () => { expect(textareaEmbed.value).toEqual(iFrameStr); }); + it('test forceDrawer', () => { + const host = "http://localhost:8081/"; + const hashPart = "#/abc/def/1"; + let expectedParam = "?forceDrawer=true"; + const iFrameStr = ""; + const cmpSharePanel = ReactDOM.render(, document.getElementById("container")); + const inputs = ReactTestUtils.scryRenderedDOMComponentsWithTag(cmpSharePanel, "input"); + let checkbox = head(inputs.filter(i => i.type === "checkbox")); + expect(checkbox.checked).toBe(false); + ReactTestUtils.Simulate.change(checkbox); + const textareaEmbed = ReactDOM.findDOMNode(ReactTestUtils.scryRenderedDOMComponentsWithTag(cmpSharePanel, "textarea")[0]); + expect(checkbox.checked).toBe(true); + expect(textareaEmbed).toExist(); + expect(textareaEmbed.value).toEqual(iFrameStr); + }); }); diff --git a/web/client/components/share/__tests__/SharePanel-test.jsx b/web/client/components/share/__tests__/SharePanel-test.jsx index 2169aec5d1..c2a2e90c87 100644 --- a/web/client/components/share/__tests__/SharePanel-test.jsx +++ b/web/client/components/share/__tests__/SharePanel-test.jsx @@ -44,7 +44,14 @@ describe("The SharePanel component", () => { expect(cmpSharePanel).toExist(); const cmpSharePanelDom = ReactDOM.findDOMNode(cmpSharePanel); expect(cmpSharePanelDom).toBeFalsy(); + }); + it('test regex parsing for shareEmbeddedUrl generation', () => { + const cmpSharePanel = ReactDOM.render(0} shareUrlRegex=".*" shareUrlReplaceString="ABC" shareUrl="www.geo-solutions.it" isVisible={false} />, document.getElementById("container")); + expect(cmpSharePanel).toExist(); + const parsed = cmpSharePanel.generateUrl("TEST", "(TE)ST", "$1"); + expect(parsed).toBe("TE"); }); + }); diff --git a/web/client/plugins/Share.jsx b/web/client/plugins/Share.jsx index 01cee3229c..1755924e5f 100644 --- a/web/client/plugins/Share.jsx +++ b/web/client/plugins/Share.jsx @@ -6,13 +6,6 @@ * LICENSE file in the root directory of this source tree. */ - /************** DESCRIPTION OF COMPONENT ************** - The share plugin should provide functionalities to: - 1. Share the map on social networks: Facebook, Twitter (linkedin and Google+ is a plus) - 2. Copy the unique link to the map. - 3. Copy a code to embed the map in your site (using an iframe). - 4. Using QR-Code for mobile devices. -*/ const React = require('react'); @@ -25,14 +18,6 @@ const ConfigUtils = require('../utils/ConfigUtils'); const Url = require('url'); - -const getEmbeddedUrl = (url) => { - let urlParsedObj = Url.parse(url, true); - - return urlParsedObj.protocol + '//' + urlParsedObj.host + urlParsedObj.path + "embedded.html#/" + - urlParsedObj.hash.substring(urlParsedObj.hash.lastIndexOf('/') + 1, urlParsedObj.hash.lastIndexOf('?')); -}; - const getApiUrl = (url) => { let urlParsedObj = Url.parse(url, true); @@ -44,11 +29,23 @@ const getConfigUrl = (url) => { return urlParsedObj.protocol + '//' + (urlParsedObj.host + urlParsedObj.path + ConfigUtils.getConfigProp('geoStoreUrl') + 'data/' + urlParsedObj.hash.substring(urlParsedObj.hash.lastIndexOf('/') + 1, urlParsedObj.hash.lastIndexOf('?'))).replace('//', '/'); }; - +/** + * Share Plugin allows to share the current URL (location.href) in some different ways. + * You can share it on socials networks(facebook,twitter,google+,linkedin) + * copying the direct link + * copying the embedded code + * using the QR code with mobile apps + * @class + * @memberof plugins + * @prop {node} [title] the title of the page + * @prop {string} [shareUrlRegex] reqular expression to parse the shareUrl to generate the final url, using shareUrlReplaceString + * @prop {string} [shareUrlReplaceString] expression to be replaced by groups of the shareUrlRegex to get the final shareUrl to use for the iframe + * @prop {function} [onClose] function to call on close window event. + * @prop {getCount} [getCount] function used to get the count for social links. + */ const Share = connect((state) => ({ isVisible: state.controls && state.controls.share && state.controls.share.enabled, shareUrl: location.href, - shareEmbeddedUrl: getEmbeddedUrl(location.href), shareApiUrl: getApiUrl(location.href), shareConfigUrl: getConfigUrl(location.href) }), {