Просмотр исходного кода

Merge pull request #2167 from weseek/imprv/copy-dropdown

Imprv/copy dropdown
Yuki Takei 5 лет назад
Родитель
Сommit
70865046d2

+ 1 - 0
resource/locales/en-US/translation.json

@@ -200,6 +200,7 @@
   "copy_to_clipboard": {
     "Copy to clipboard": "Copy to clipboard",
     "Page path": "Page path",
+    "Page URL": "Page URL",
     "Parmanent link": "Parmanent link",
     "Page path and parmanent link": "Page path and parmanent link",
     "Markdown link": "Markdown link"

+ 1 - 0
resource/locales/ja/translation.json

@@ -199,6 +199,7 @@
   "copy_to_clipboard": {
     "Copy to clipboard": "クリップボードにコピー",
     "Page path": "ページ名",
+    "Page URL": "ページURL",
     "Parmanent link": "パーマリンク",
     "Page path and parmanent link": "ページ名とパーマリンク",
     "Markdown link": "マークダウン形式のリンク"

+ 89 - 43
src/client/js/components/Page/CopyDropdown.jsx

@@ -15,9 +15,6 @@ class CopyDropdown extends React.Component {
   constructor(props) {
     super(props);
 
-    // retrieve xss library from window
-    this.xss = window.xss;
-
     this.state = {
       dropdownOpen: false,
       tooltipOpen: false,
@@ -25,7 +22,10 @@ class CopyDropdown extends React.Component {
 
     this.toggle = this.toggle.bind(this);
     this.showToolTip = this.showToolTip.bind(this);
-    this.generatePageUrl = this.generatePageUrl.bind(this);
+    this.generatePagePathWithParams = this.generatePagePathWithParams.bind(this);
+    this.generatePagePathUrl = this.generatePagePathUrl.bind(this);
+    this.generatePermalink = this.generatePermalink.bind(this);
+    this.generateMarkdownLink = this.generateMarkdownLink.bind(this);
   }
 
   toggle() {
@@ -39,25 +39,65 @@ class CopyDropdown extends React.Component {
     }, 1000);
   }
 
-  generatePageUrl() {
-    return (this.props.pageId == null)
-      ? decodeURIComponent(window.location.pathname + window.location.search)
-      : `${window.location.origin}/${this.props.pageId}`;
+  generatePagePathWithParams() {
+    const { pagePath } = this.props;
+    const {
+      search, hash,
+    } = window.location;
+
+    return decodeURI(`${pagePath}${search}${hash}`);
+  }
+
+  generatePagePathUrl() {
+    const { origin } = window.location;
+    return `${origin}${this.generatePagePathWithParams()}`;
+  }
+
+  generatePermalink() {
+    const { pageId } = this.props;
+    const { location } = window;
+
+    if (pageId == null) {
+      return null;
+    }
+
+    const {
+      origin, search, hash,
+    } = location;
+    return decodeURI(`${origin}/${pageId}${search}${hash}`);
   }
 
   generateMarkdownLink() {
-    return;
+    const { pagePath } = this.props;
+    const {
+      search, hash,
+    } = window.location;
+
+    const label = `${pagePath}${search}${hash}`;
+    const permalink = this.generatePermalink();
+
+    return decodeURI(`[${label}](${permalink})`);
   }
 
+  DropdownItemContents = ({ title, contents }) => (
+    <>
+      <div className="h6 mt-1 mb-2"><strong>{title}</strong></div>
+      <div className="card well mb-1 p-2">{contents}</div>
+    </>
+  );
+
   render() {
-    const { t } = this.props;
+    const { t, pageId } = this.props;
+
+    const pagePathWithParams = this.generatePagePathWithParams();
+    const pagePathUrl = this.generatePagePathUrl();
+    const permalink = this.generatePermalink();
 
-    const safePagePath = this.xss.process(this.props.pagePath);
-    const url = this.generatePageUrl();
+    const { DropdownItemContents } = this;
 
     return (
       <>
-        <Dropdown id="copyPagePathDropdown" isOpen={this.state.dropdownOpen} toggle={this.toggle}>
+        <Dropdown id="copyPagePathDropdown" className="grw-copy-dropdown" isOpen={this.state.dropdownOpen} toggle={this.toggle}>
 
           <DropdownToggle
             caret
@@ -68,49 +108,55 @@ class CopyDropdown extends React.Component {
           </DropdownToggle>
 
           <DropdownMenu>
-            <h5 className="ml-3 my-0 text-muted">{ t('copy_to_clipboard.Copy to clipboard') }</h5>
-            <DropdownItem divider></DropdownItem>
+            <DropdownItem header className="px-3">{ t('copy_to_clipboard.Copy to clipboard') }</DropdownItem>
+
+            <DropdownItem divider className="my-0"></DropdownItem>
 
             {/* Page path */}
-            <CopyToClipboard text={this.props.pagePath} onCopy={this.showToolTip}>
-              <DropdownItem tag="a">
-                <div className="d-inline-flex flex-column">
-                  <h6 className="mt-1 mb-2"><strong>{ t('copy_to_clipboard.Page path') }</strong></h6>
-                  <span className="small">{safePagePath}</span>
-                </div>
+            <CopyToClipboard text={pagePathWithParams} onCopy={this.showToolTip}>
+              <DropdownItem className="px-3">
+                <DropdownItemContents title={t('copy_to_clipboard.Page path')} contents={pagePathWithParams} />
+              </DropdownItem>
+            </CopyToClipboard>
+
+            <DropdownItem divider className="my-0"></DropdownItem>
+
+            {/* Page path URL */}
+            <CopyToClipboard text={pagePathUrl} onCopy={this.showToolTip}>
+              <DropdownItem className="px-3">
+                <DropdownItemContents title={t('copy_to_clipboard.Page URL')} contents={pagePathUrl} />
               </DropdownItem>
             </CopyToClipboard>
+
+            <DropdownItem divider className="my-0"></DropdownItem>
+
             {/* Parmanent Link */}
-            { this.props.pageId && (
-              <CopyToClipboard text={url} onCopy={this.showToolTip}>
-                <DropdownItem tag="a">
-                  <div className="d-inline-flex flex-column">
-                    <h6 className="mt-1 mb-2"><strong>{ t('copy_to_clipboard.Parmanent link') }</strong></h6>
-                    <span className="small">{url}</span>
-                  </div>
+            { pageId && (
+              <CopyToClipboard text={permalink} onCopy={this.showToolTip}>
+                <DropdownItem className="px-3">
+                  <DropdownItemContents title={t('copy_to_clipboard.Parmanent link')} contents={permalink} />
                 </DropdownItem>
               </CopyToClipboard>
             )}
+
+            <DropdownItem divider className="my-0"></DropdownItem>
+
             {/* Page path + Parmanent Link */}
-            { this.props.pageId && (
-              <CopyToClipboard text={`${this.props.pagePath}\n${url}`} onCopy={this.showToolTip}>
-                <DropdownItem tag="a">
-                  <div className="d-inline-flex flex-column">
-                    <h6 className="mt-1 mb-2"><strong>{ t('copy_to_clipboard.Page path and parmanent link') }</strong></h6>
-                    <span className="small mb-3">{safePagePath}</span>
-                    <span className="small">{url}</span>
-                  </div>
+            { pageId && (
+              <CopyToClipboard text={`${pagePathWithParams}\n${permalink}`} onCopy={this.showToolTip}>
+                <DropdownItem className="px-3">
+                  <DropdownItemContents title={t('copy_to_clipboard.Page path and parmanent link')} contents={<>{pagePathWithParams}<br />{permalink}</>} />
                 </DropdownItem>
               </CopyToClipboard>
             )}
+
+            <DropdownItem divider className="my-0"></DropdownItem>
+
             {/* Markdown Link */}
-            { this.props.pageId && (
-              <CopyToClipboard text={`[${this.props.pagePath}](${url})`} onCopy={this.showToolTip}>
-                <DropdownItem tag="a">
-                  <div className="d-inline-flex flex-column">
-                    <h6 className="mt-1 mb-2"><strong>{ t('copy_to_clipboard.Markdown link') }</strong></h6>
-                    <span className="small">{`[${safePagePath}](${url})`}</span>
-                  </div>
+            { pageId && (
+              <CopyToClipboard text={this.generateMarkdownLink()} onCopy={this.showToolTip}>
+                <DropdownItem className="px-3 text-wrap">
+                  <DropdownItemContents title={t('copy_to_clipboard.Markdown link')} contents={this.generateMarkdownLink()} isContentsWrap />
                 </DropdownItem>
               </CopyToClipboard>
             )}

+ 19 - 0
src/client/styles/scss/molecules/copy-dropdown.scss

@@ -0,0 +1,19 @@
+.grw-copy-dropdown {
+  .dropdown-menu {
+    .dropdown-header {
+      margin-bottom: 0.5em;
+      font-size: 1.1em;
+    }
+
+    // unset active styles
+    .dropdown-item:active {
+      color: unset;
+      background-color: unset;
+    }
+
+    .well {
+      font-size: 0.6em;
+      word-break: break-all;
+    }
+  }
+}

+ 3 - 0
src/client/styles/scss/style-app.scss

@@ -20,6 +20,9 @@
 @import 'atoms/spinners';
 @import 'atoms/custom_control';
 
+// molecules
+@import 'molecules/copy-dropdown';
+
 // growi component
 @import 'admin';
 @import 'attachments';