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

Merge branch 'master' into imprv/take-over-tags-from-template-page

# Conflicts:
#	src/client/js/app.js
yusuketk 7 лет назад
Родитель
Сommit
84967d9f5b

+ 4 - 0
CHANGES.md

@@ -2,6 +2,10 @@
 
 
 ## 3.4.6-RC
 ## 3.4.6-RC
 
 
+* Feature: Append tags to pages
+* Feature: Dropdown to copy page path/URL/MarkdownLink
+* Feature: List of drafts
+* Improvement: Replace icons of Editor Tool Bar
 * Improvement: Show display name when mouse hover to user image
 * Improvement: Show display name when mouse hover to user image
 * Fix: URL in slack message is broken on Safari
 * Fix: URL in slack message is broken on Safari
 * Fix: Registration does not work when basic auth is enabled
 * Fix: Registration does not work when basic auth is enabled

+ 1 - 2
config/webpack.dev.dll.js

@@ -14,7 +14,6 @@ module.exports = {
       'babel-polyfill',
       'babel-polyfill',
       'browser-bunyan', 'bunyan-format',
       'browser-bunyan', 'bunyan-format',
       'codemirror', 'react-codemirror2',
       'codemirror', 'react-codemirror2',
-      'clipboard',
       'date-fns',
       'date-fns',
       'diff2html',
       'diff2html',
       'debug',
       'debug',
@@ -24,7 +23,7 @@ module.exports = {
       'lodash', 'pako',
       'lodash', 'pako',
       'markdown-it', 'csv-to-markdown-table',
       'markdown-it', 'csv-to-markdown-table',
       'react', 'react-dom',
       'react', 'react-dom',
-      'react-bootstrap', 'react-bootstrap-typeahead', 'react-i18next', 'react-dropzone',
+      'react-bootstrap', 'react-bootstrap-typeahead', 'react-i18next', 'react-dropzone', 'react-copy-to-clipboard',
       'socket.io-client',
       'socket.io-client',
       'toastr',
       'toastr',
       'xss',
       'xss',

+ 1 - 1
package.json

@@ -196,8 +196,8 @@
     "react": "^16.8.3",
     "react": "^16.8.3",
     "react-bootstrap": "^0.32.1",
     "react-bootstrap": "^0.32.1",
     "react-bootstrap-typeahead": "^3.4.2",
     "react-bootstrap-typeahead": "^3.4.2",
-    "react-clipboard.js": "^2.0.0",
     "react-codemirror2": "^6.0.0",
     "react-codemirror2": "^6.0.0",
+    "react-copy-to-clipboard": "^5.0.1",
     "react-dom": "^16.8.3",
     "react-dom": "^16.8.3",
     "react-frame-component": "^4.0.0",
     "react-frame-component": "^4.0.0",
     "react-i18next": "^10.6.1",
     "react-i18next": "^10.6.1",

+ 1 - 1
public/images/icons/editor/bold.svg

@@ -1 +1 @@
-<svg xmlns="http://www.w3.org/2000/svg" height="13" viewBox="0 0 10.9 14"><path d="M0 0h5.6c3 0 4.7 1.1 4.7 3.4a3.1 3.1 0 0 1-2.5 3.1 3.7 3.7 0 0 1 3.1 3.5c0 2.9-1.4 4-4.2 4H0zm5.2 6.5c2.7 0 2.6-1.4 2.6-3.1S7.9.7 5.6.7H2.3v5.8zm-2.9 6.6h3.4c2.1 0 2.7-1.1 2.7-3.1s0-2.8-3.2-2.8H2.3z"/></svg>
+<svg xmlns="http://www.w3.org/2000/svg" width="109" height="140" viewBox="0 0 10.9 14"><path d="M0 0h5.6c3 0 4.7 1.1 4.7 3.4a3.1 3.1 0 0 1-2.5 3.1 3.7 3.7 0 0 1 3.1 3.5c0 2.9-1.4 4-4.2 4H0zm5.2 6.5c2.7 0 2.6-1.4 2.6-3.1S7.9.7 5.6.7H2.3v5.8zm-2.9 6.6h3.4c2.1 0 2.7-1.1 2.7-3.1s0-2.8-3.2-2.8H2.3z"/></svg>

+ 1 - 1
public/images/icons/editor/check.svg

@@ -1 +1 @@
-<svg xmlns="http://www.w3.org/2000/svg" height="13" viewBox="0 0 14.4 16"><path d="M13.9 5.5a.5.5 0 0 1 .5.5v9a1.1 1.1 0 0 1-1.1 1H1a1.1 1.1 0 0 1-1-1V2.6a1.1 1.1 0 0 1 1-1h7.1a.5.5 0 0 1 .5.5.5.5 0 0 1-.5.5H1V15h12.3V6a.6.6 0 0 1 .6-.5zM3.6 8.3a.5.5 0 0 0 0 .7l2.5 2.5a.8.8 0 0 0 1.1 0h.1l7-10.7c.1-.2.1-.6-.2-.7a.5.5 0 0 0-.7.1L6.6 10.6 4.3 8.3a.5.5 0 0 0-.7 0z"/></svg>
+<svg xmlns="http://www.w3.org/2000/svg" width="144" height="160" viewBox="0 0 14.4 16"><path d="M13.9 5.5a.5.5 0 0 1 .5.5v9a1.1 1.1 0 0 1-1.1 1H1a1.1 1.1 0 0 1-1-1V2.6a1.1 1.1 0 0 1 1-1h7.1a.5.5 0 0 1 .5.5.5.5 0 0 1-.5.5H1V15h12.3V6a.6.6 0 0 1 .6-.5zM3.6 8.3a.5.5 0 0 0 0 .7l2.5 2.5a.8.8 0 0 0 1.1 0h.1l7-10.7c.1-.2.1-.6-.2-.7a.5.5 0 0 0-.7.1L6.6 10.6 4.3 8.3a.5.5 0 0 0-.7 0z"/></svg>

+ 1 - 1
public/images/icons/editor/code.svg

@@ -1 +1 @@
-<svg xmlns="http://www.w3.org/2000/svg" height="13" viewBox="0 0 18.1 14"><path d="M17.8 7.9l-4 3.8a.5.5 0 0 1-.8 0 .5.5 0 0 1 0-.8L16.8 7 13 3.2a.6.6 0 0 1 0-.9.5.5 0 0 1 .8 0l4 3.8a1.3 1.3 0 0 1 0 1.8zM5.2 2.3a.7.7 0 0 1 0 .9L1.3 7l3.9 3.9a.6.6 0 0 1 0 .8.6.6 0 0 1-.9 0L.4 7.9a1.3 1.3 0 0 1 0-1.8l3.9-3.8a.6.6 0 0 1 .9 0zM11.5.8L7.8 13.6a.6.6 0 0 1-.7.4.6.6 0 0 1-.5-.8L10.3.4a.7.7 0 0 1 .8-.4.6.6 0 0 1 .4.8z"/></svg>
+<svg xmlns="http://www.w3.org/2000/svg" width="181" height="140" viewBox="0 0 18.1 14"><path d="M17.8 7.9l-4 3.8a.5.5 0 0 1-.8 0 .5.5 0 0 1 0-.8L16.8 7 13 3.2a.6.6 0 0 1 0-.9.5.5 0 0 1 .8 0l4 3.8a1.3 1.3 0 0 1 0 1.8zM5.2 2.3a.7.7 0 0 1 0 .9L1.3 7l3.9 3.9a.6.6 0 0 1 0 .8.6.6 0 0 1-.9 0L.4 7.9a1.3 1.3 0 0 1 0-1.8l3.9-3.8a.6.6 0 0 1 .9 0zM11.5.8L7.8 13.6a.6.6 0 0 1-.7.4.6.6 0 0 1-.5-.8L10.3.4a.7.7 0 0 1 .8-.4.6.6 0 0 1 .4.8z"/></svg>

+ 1 - 1
public/images/icons/editor/header.svg

@@ -1 +1 @@
-<svg xmlns="http://www.w3.org/2000/svg" height="13" viewBox="0 0 13.7 14"><path d="M10.2 0h2.9a.6.6 0 0 1 .6.6.6.6 0 0 1-.6.6h-.8v11.6h.8a.6.6 0 0 1 .6.6.6.6 0 0 1-.6.6h-2.9a.6.6 0 0 1-.6-.6.6.6 0 0 1 .6-.6h.8V7.2H2.7v5.6h.8a.6.6 0 0 1 .6.6.6.6 0 0 1-.6.6H.6a.6.6 0 0 1-.6-.6.6.6 0 0 1 .6-.6h.7V1.2H.6A.6.6 0 0 1 0 .6.6.6 0 0 1 .6 0h2.9a.6.6 0 0 1 .6.6.6.6 0 0 1-.6.6h-.8v4.9H11V1.2h-.8a.6.6 0 0 1-.6-.6.6.6 0 0 1 .6-.6z"/></svg>
+<svg xmlns="http://www.w3.org/2000/svg" width="137" height="140" viewBox="0 0 13.7 14"><path d="M10.2 0h2.9a.6.6 0 0 1 .6.6.6.6 0 0 1-.6.6h-.8v11.6h.8a.6.6 0 0 1 .6.6.6.6 0 0 1-.6.6h-2.9a.6.6 0 0 1-.6-.6.6.6 0 0 1 .6-.6h.8V7.2H2.7v5.6h.8a.6.6 0 0 1 .6.6.6.6 0 0 1-.6.6H.6a.6.6 0 0 1-.6-.6.6.6 0 0 1 .6-.6h.7V1.2H.6A.6.6 0 0 1 0 .6.6.6 0 0 1 .6 0h2.9a.6.6 0 0 1 .6.6.6.6 0 0 1-.6.6h-.8v4.9H11V1.2h-.8a.6.6 0 0 1-.6-.6.6.6 0 0 1 .6-.6z"/></svg>

+ 1 - 1
public/images/icons/editor/italic.svg

@@ -1 +1 @@
-<svg xmlns="http://www.w3.org/2000/svg" height="13" viewBox="0 0 8.6 13.9"><path d="M8.1 0a.6.6 0 0 1 .5.6c0 .3-.2.6-.7.6H6.2L3.8 12.8h1.8c.2 0 .4.3.4.5a.7.7 0 0 1-.7.6H.5c-.3 0-.5-.4-.5-.6s.4-.6.7-.6h1.7L4.9 1.2H3.1a.5.5 0 0 1-.5-.5c0-.3.1-.7.8-.7z"/></svg>
+<svg xmlns="http://www.w3.org/2000/svg" width="86" height="139" viewBox="0 0 8.6 13.9"><path d="M8.1 0a.6.6 0 0 1 .5.6c0 .3-.2.6-.7.6H6.2L3.8 12.8h1.8c.2 0 .4.3.4.5a.7.7 0 0 1-.7.6H.5c-.3 0-.5-.4-.5-.6s.4-.6.7-.6h1.7L4.9 1.2H3.1a.5.5 0 0 1-.5-.5c0-.3.1-.7.8-.7z"/></svg>

+ 1 - 1
public/images/icons/editor/link.svg

@@ -1 +1 @@
-<svg xmlns="http://www.w3.org/2000/svg" height="13" viewBox="0 0 16 16"><path d="M4.6 11.4l.4.2h.2v-.2l6.1-6.1a.4.4 0 0 0 .1-.3.5.5 0 0 0-.5-.5h-.3l-6 6.2a.6.6 0 0 0-.1.4c0 .1 0 .3.1.3zm2.8-1a2 2 0 0 1 0 1.1 4.1 4.1 0 0 1-.5.9l-2.1 1.9a1.9 1.9 0 0 1-1.5.7 2 2 0 0 1-1.6-.7 1.9 1.9 0 0 1-.7-1.5 2 2 0 0 1 .7-1.6l1.9-2.1a2 2 0 0 1 2.2-.5l.8-.8a3.2 3.2 0 0 0-1.4-.3 3.3 3.3 0 0 0-2.3.9L1 10.5A3.2 3.2 0 0 0 .9 15H1a2.9 2.9 0 0 0 2.3 1 3.2 3.2 0 0 0 2.3-1l2-1.9a4.6 4.6 0 0 0 .9-1.7 2.9 2.9 0 0 0-.3-1.8zM15 1a2.5 2.5 0 0 0-1-.8 3.1 3.1 0 0 0-3.5.8L8.4 2.9a3.1 3.1 0 0 0-.9 1.8 3.2 3.2 0 0 0 .3 1.9l.8-.8a2 2 0 0 1 0-1.1 2.2 2.2 0 0 1 .5-1.1l2.1-1.9.3-.3.4-.2.4-.2h.5a1.9 1.9 0 0 1 1.5.7 2 2 0 0 1 .7 1.6 1.9 1.9 0 0 1-.7 1.5l-2 2.1-.7.4a1.5 1.5 0 0 1-.9.2h-.4l-.8.8H12l1-.7 2-2.1A3 3 0 0 0 15 1z"/></svg>
+<svg xmlns="http://www.w3.org/2000/svg" width="160" height="160" viewBox="0 0 16 16"><path d="M4.6 11.4l.4.2h.2v-.2l6.1-6.1a.4.4 0 0 0 .1-.3.5.5 0 0 0-.5-.5h-.3l-6 6.2a.6.6 0 0 0-.1.4c0 .1 0 .3.1.3zm2.8-1a2 2 0 0 1 0 1.1 4.1 4.1 0 0 1-.5.9l-2.1 1.9a1.9 1.9 0 0 1-1.5.7 2 2 0 0 1-1.6-.7 1.9 1.9 0 0 1-.7-1.5 2 2 0 0 1 .7-1.6l1.9-2.1a2 2 0 0 1 2.2-.5l.8-.8a3.2 3.2 0 0 0-1.4-.3 3.3 3.3 0 0 0-2.3.9L1 10.5A3.2 3.2 0 0 0 .9 15H1a2.9 2.9 0 0 0 2.3 1 3.2 3.2 0 0 0 2.3-1l2-1.9a4.6 4.6 0 0 0 .9-1.7 2.9 2.9 0 0 0-.3-1.8zM15 1a2.5 2.5 0 0 0-1-.8 3.1 3.1 0 0 0-3.5.8L8.4 2.9a3.1 3.1 0 0 0-.9 1.8 3.2 3.2 0 0 0 .3 1.9l.8-.8a2 2 0 0 1 0-1.1 2.2 2.2 0 0 1 .5-1.1l2.1-1.9.3-.3.4-.2.4-.2h.5a1.9 1.9 0 0 1 1.5.7 2 2 0 0 1 .7 1.6 1.9 1.9 0 0 1-.7 1.5l-2 2.1-.7.4a1.5 1.5 0 0 1-.9.2h-.4l-.8.8H12l1-.7 2-2.1A3 3 0 0 0 15 1z"/></svg>

+ 1 - 1
public/images/icons/editor/list-ol.svg

@@ -1 +1 @@
-<svg xmlns="http://www.w3.org/2000/svg" height="13" viewBox="0 0 23.7 16"><path d="M23.7 2a.8.8 0 0 1-.8.8H6.6a.8.8 0 0 1-.7-.8.7.7 0 0 1 .7-.7h16.3a.7.7 0 0 1 .8.7zM6.6 8.7h16.3a.7.7 0 0 0 .8-.7.8.8 0 0 0-.8-.8H6.6a.8.8 0 0 0-.7.8.7.7 0 0 0 .7.7zm0 5.9h16.3a.7.7 0 0 0 .8-.7.7.7 0 0 0-.8-.7H6.6a.7.7 0 0 0-.7.7.7.7 0 0 0 .7.7zM1.5.5V4h.6V0h-.5L.7.5v.4l.8-.4zM.9 9.6l.3-.3c.9-.9 1.4-1.5 1.4-2.2a1.2 1.2 0 0 0-1.3-1.2h-.1a1.4 1.4 0 0 0-1.2.6l.3.4a1.2 1.2 0 0 1 .9-.5.6.6 0 0 1 .8.6v.2c0 .6-.4 1.1-1.5 2.1l-.4.4v.3h2.6v-.4zm.9 4.1a1 1 0 0 0 .7-.9 1 1 0 0 0-1.1-1 2 2 0 0 0-1.1.3v.4l.8-.2c.5 0 .8.2.8.6s-.5.7-.9.7H.7v.4H1c.6 0 1.1.2 1.1.8a.8.8 0 0 1-.9.8l-.9-.3-.2.4a2 2 0 0 0 1.1.3c1 0 1.5-.6 1.5-1.2a1.2 1.2 0 0 0-.9-1.1z"/></svg>
+<svg xmlns="http://www.w3.org/2000/svg" width="237" height="160" viewBox="0 0 23.7 16"><path d="M23.7 2a.8.8 0 0 1-.8.8H6.6a.8.8 0 0 1-.7-.8.7.7 0 0 1 .7-.7h16.3a.7.7 0 0 1 .8.7zM6.6 8.7h16.3a.7.7 0 0 0 .8-.7.8.8 0 0 0-.8-.8H6.6a.8.8 0 0 0-.7.8.7.7 0 0 0 .7.7zm0 5.9h16.3a.7.7 0 0 0 .8-.7.7.7 0 0 0-.8-.7H6.6a.7.7 0 0 0-.7.7.7.7 0 0 0 .7.7zM1.5.5V4h.6V0h-.5L.7.5v.4l.8-.4zM.9 9.6l.3-.3c.9-.9 1.4-1.5 1.4-2.2a1.2 1.2 0 0 0-1.3-1.2h-.1a1.4 1.4 0 0 0-1.2.6l.3.4a1.2 1.2 0 0 1 .9-.5.6.6 0 0 1 .8.6v.2c0 .6-.4 1.1-1.5 2.1l-.4.4v.3h2.6v-.4zm.9 4.1a1 1 0 0 0 .7-.9 1 1 0 0 0-1.1-1 2 2 0 0 0-1.1.3v.4l.8-.2c.5 0 .8.2.8.6s-.5.7-.9.7H.7v.4H1c.6 0 1.1.2 1.1.8a.8.8 0 0 1-.9.8l-.9-.3-.2.4a2 2 0 0 0 1.1.3c1 0 1.5-.6 1.5-1.2a1.2 1.2 0 0 0-.9-1.1z"/></svg>

+ 1 - 1
public/images/icons/editor/list-ul.svg

@@ -1 +1 @@
-<svg xmlns="http://www.w3.org/2000/svg" height="13" viewBox="0 0 21.6 13.5"><path d="M6.4 1.5h14.5a.7.7 0 0 0 .7-.7.7.7 0 0 0-.7-.7H6.4a.8.8 0 0 0-.8.7.8.8 0 0 0 .8.7zM6.4 7.5h14.5a.7.7 0 0 0 .7-.7.7.7 0 0 0-.7-.7H6.4a.8.8 0 0 0-.8.7.8.8 0 0 0 .8.7zM6.4 13.5h14.5a.7.7 0 0 0 .7-.7.7.7 0 0 0-.7-.7H6.4a.8.8 0 0 0-.8.7.8.8 0 0 0 .8.7zM.9 1.5h1a.8.8 0 0 0 .9-.7.8.8 0 0 0-.9-.8h-1a.8.8 0 0 0-.9.7.8.8 0 0 0 .9.8zM.9 7.5h1a.8.8 0 0 0 .9-.7.8.8 0 0 0-.9-.8h-1a.8.8 0 0 0-.9.7.8.8 0 0 0 .9.8zM.9 13.5h1a.8.8 0 0 0 .9-.7.8.8 0 0 0-.9-.7h-1a.8.8 0 0 0-.9.7.8.8 0 0 0 .9.7z"/></svg>
+<svg xmlns="http://www.w3.org/2000/svg" width="216" height="135" viewBox="0 0 21.6 13.5"><path d="M6.4 1.5h14.5a.7.7 0 0 0 .7-.7.7.7 0 0 0-.7-.7H6.4a.8.8 0 0 0-.8.7.8.8 0 0 0 .8.7zm0 6h14.5a.7.7 0 0 0 .7-.7.7.7 0 0 0-.7-.7H6.4a.8.8 0 0 0-.8.7.8.8 0 0 0 .8.7zm0 6h14.5a.7.7 0 0 0 .7-.7.7.7 0 0 0-.7-.7H6.4a.8.8 0 0 0-.8.7.8.8 0 0 0 .8.7zM.9 1.5h1a.8.8 0 0 0 .9-.7.8.8 0 0 0-.9-.8h-1a.8.8 0 0 0-.9.7.8.8 0 0 0 .9.8zm0 6h1a.8.8 0 0 0 .9-.7.8.8 0 0 0-.9-.8h-1a.8.8 0 0 0-.9.7.8.8 0 0 0 .9.8zm0 6h1a.8.8 0 0 0 .9-.7.8.8 0 0 0-.9-.7h-1a.8.8 0 0 0-.9.7.8.8 0 0 0 .9.7z"/></svg>

+ 1 - 1
public/images/icons/editor/picture.svg

@@ -1 +1 @@
-<svg xmlns="http://www.w3.org/2000/svg" height="13" viewBox="0 0 19 16"><path d="M17.8 0H1.2A1.2 1.2 0 0 0 0 1.2v13.6A1.2 1.2 0 0 0 1.2 16h16.6a1.2 1.2 0 0 0 1.2-1.2V1.2a1.4 1.4 0 0 0-.2-.6.8.8 0 0 0-.4-.4zm0 14.8H1.2v-3.5l4.7-4.6 5 4.9.3.2.5-.2 2.1-1.9 3.9 4h.1v1.1zm0-2.8l-3.5-3.5-.4-.2h-.4l-2.2 2-4.9-4.8-.4-.2c-.2 0-.4 0-.5.2L1.2 9.7V1.2h16.6V12zm-4.2-6.1h.6a1.1 1.1 0 0 0 .6-1.1 1.2 1.2 0 0 0-1.2-1.1 1.3 1.3 0 0 0-1.2 1.2 1.2 1.2 0 0 0 .4.8 1.1 1.1 0 0 0 .8.3z"/></svg>
+<svg xmlns="http://www.w3.org/2000/svg" width="190" height="160" viewBox="0 0 19 16"><path d="M17.8 0H1.2A1.2 1.2 0 0 0 0 1.2v13.6A1.2 1.2 0 0 0 1.2 16h16.6a1.2 1.2 0 0 0 1.2-1.2V1.2a1.4 1.4 0 0 0-.2-.6.8.8 0 0 0-.4-.4zm0 14.8H1.2v-3.5l4.7-4.6 5 4.9.3.2.5-.2 2.1-1.9 3.9 4h.1v1.1zm0-2.8l-3.5-3.5-.4-.2h-.4l-2.2 2-4.9-4.8-.4-.2c-.2 0-.4 0-.5.2L1.2 9.7V1.2h16.6V12zm-4.2-6.1h.6a1.1 1.1 0 0 0 .6-1.1 1.2 1.2 0 0 0-1.2-1.1 1.3 1.3 0 0 0-1.2 1.2 1.2 1.2 0 0 0 .4.8 1.1 1.1 0 0 0 .8.3z"/></svg>

+ 1 - 1
public/images/icons/editor/quote.svg

@@ -1 +1 @@
-<svg xmlns="http://www.w3.org/2000/svg" height="13" viewBox="0 0 17 12"><path d="M5 0H2a2 2 0 0 0-2 2v3a2 2 0 0 0 2 2h3a1.7 1.7 0 0 0 1-.3V10a.9.9 0 0 1-1 1H3v1h2a2 2 0 0 0 2-2V2a2 2 0 0 0-2-2zm0 6H2a.9.9 0 0 1-1-1V2a.9.9 0 0 1 1-1h3a.9.9 0 0 1 1 1v3a.9.9 0 0 1-1 1zM15 0h-3a2 2 0 0 0-2 2v3a2 2 0 0 0 2 2h3a1.7 1.7 0 0 0 1-.3V10a.9.9 0 0 1-1 1h-2v1h2a2 2 0 0 0 2-2V2a2 2 0 0 0-2-2zm0 6h-3a.9.9 0 0 1-1-1V2a.9.9 0 0 1 1-1h3a.9.9 0 0 1 1 1v3a.9.9 0 0 1-1 1z"/></svg>
+<svg xmlns="http://www.w3.org/2000/svg" width="170" height="120" viewBox="0 0 17 12"><path d="M5 0H2a2 2 0 0 0-2 2v3a2 2 0 0 0 2 2h3a1.7 1.7 0 0 0 1-.3V10a.9.9 0 0 1-1 1H3v1h2a2 2 0 0 0 2-2V2a2 2 0 0 0-2-2zm0 6H2a.9.9 0 0 1-1-1V2a.9.9 0 0 1 1-1h3a.9.9 0 0 1 1 1v3a.9.9 0 0 1-1 1zm10-6h-3a2 2 0 0 0-2 2v3a2 2 0 0 0 2 2h3a1.7 1.7 0 0 0 1-.3V10a.9.9 0 0 1-1 1h-2v1h2a2 2 0 0 0 2-2V2a2 2 0 0 0-2-2zm0 6h-3a.9.9 0 0 1-1-1V2a.9.9 0 0 1 1-1h3a.9.9 0 0 1 1 1v3a.9.9 0 0 1-1 1z"/></svg>

+ 1 - 1
public/images/icons/editor/strikethrough.svg

@@ -1 +1 @@
-<svg xmlns="http://www.w3.org/2000/svg" height="13" viewBox="0 0 19.5 14"><path d="M5.8 6.2H9C7.2 5.7 6.3 5 6.3 3.8a2.2 2.2 0 0 1 .9-1.9 4.3 4.3 0 0 1 2.5-.7 4.3 4.3 0 0 1 2.5.7 3.1 3.1 0 0 1 1.1 1.6.7.7 0 0 0 .6.4h.3a.7.7 0 0 0 .4-.8A3.6 3.6 0 0 0 13.1 1a6.7 6.7 0 0 0-6-.5 3.1 3.1 0 0 0-1.7 1.3 3.6 3.6 0 0 0-.6 2 2.9 2.9 0 0 0 1 2.3zM12.8 8.7a2 2 0 0 1 .6 1.4 2.4 2.4 0 0 1-1 1.9 3.7 3.7 0 0 1-2.5.7 4.6 4.6 0 0 1-3-.8 3.7 3.7 0 0 1-1.2-2 .6.6 0 0 0-.6-.5h-.2a.7.7 0 0 0-.5.8 4.1 4.1 0 0 0 1.5 2.5A6 6 0 0 0 9.8 14a7.5 7.5 0 0 0 2.6-.5 4.9 4.9 0 0 0 1.8-1.4 4.3 4.3 0 0 0 .6-2.2 5 5 0 0 0-.2-1.2zM.4 7.9a.7.7 0 0 1-.4-.5.4.4 0 0 1 .4-.4h18.8a.4.4 0 0 1 .3.6c0 .1-.1.2-.2.3z"/></svg>
+<svg xmlns="http://www.w3.org/2000/svg" width="195" height="140" viewBox="0 0 19.5 14"><path d="M5.8 6.2H9C7.2 5.7 6.3 5 6.3 3.8a2.2 2.2 0 0 1 .9-1.9 4.3 4.3 0 0 1 2.5-.7 4.3 4.3 0 0 1 2.5.7 3.1 3.1 0 0 1 1.1 1.6.7.7 0 0 0 .6.4h.3a.7.7 0 0 0 .4-.8A3.6 3.6 0 0 0 13.1 1a6.7 6.7 0 0 0-6-.5 3.1 3.1 0 0 0-1.7 1.3 3.6 3.6 0 0 0-.6 2 2.9 2.9 0 0 0 1 2.3zm7 2.5a2 2 0 0 1 .6 1.4 2.4 2.4 0 0 1-1 1.9 3.7 3.7 0 0 1-2.5.7 4.6 4.6 0 0 1-3-.8 3.7 3.7 0 0 1-1.2-2 .6.6 0 0 0-.6-.5h-.2a.7.7 0 0 0-.5.8 4.1 4.1 0 0 0 1.5 2.5A6 6 0 0 0 9.8 14a7.5 7.5 0 0 0 2.6-.5 4.9 4.9 0 0 0 1.8-1.4 4.3 4.3 0 0 0 .6-2.2 5 5 0 0 0-.2-1.2zM.4 7.9a.7.7 0 0 1-.4-.5.4.4 0 0 1 .4-.4h18.8a.4.4 0 0 1 .3.6c0 .1-.1.2-.2.3z"/></svg>

+ 1 - 1
public/images/icons/editor/table.svg

@@ -1 +1 @@
-<svg xmlns="http://www.w3.org/2000/svg" height="13" viewBox="0 0 20.3 16"><path d="M19.1 16H1.2A1.2 1.2 0 0 1 0 14.8V1.2A1.2 1.2 0 0 1 1.2 0h17.9a1.2 1.2 0 0 1 1.2 1.2v13.6a1.2 1.2 0 0 1-1.2 1.2zm-5.2-4.3v3.2h5.3v-3.2zm-6.4 0v3.2h5.3v-3.2zm-6.4 0v3.2h5.3v-3.2zm12.8-4.2v3.2h5.3V7.5zm-6.4 0v3.2h5.3V7.5zm-6.4 0v3.2h5.3V7.5zm12.8-4.3v3.2h5.3V3.2zm-6.4 0v3.2h5.3V3.2zm-6.4 0v3.2h5.3V3.2z"/></svg>
+<svg xmlns="http://www.w3.org/2000/svg" width="203" height="160" viewBox="0 0 20.3 16"><path d="M19.1 16H1.2A1.2 1.2 0 0 1 0 14.8V1.2A1.2 1.2 0 0 1 1.2 0h17.9a1.2 1.2 0 0 1 1.2 1.2v13.6a1.2 1.2 0 0 1-1.2 1.2zm-5.2-4.3v3.2h5.3v-3.2zm-6.4 0v3.2h5.3v-3.2zm-6.4 0v3.2h5.3v-3.2zm12.8-4.2v3.2h5.3V7.5zm-6.4 0v3.2h5.3V7.5zm-6.4 0v3.2h5.3V7.5zm12.8-4.3v3.2h5.3V3.2zm-6.4 0v3.2h5.3V3.2zm-6.4 0v3.2h5.3V3.2z"/></svg>

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

@@ -200,6 +200,14 @@
     }
     }
   },
   },
 
 
+  "copy_to_clipboard": {
+    "Copy to clipboard": "クリップボードにコピー",
+    "Page path": "ページ名",
+    "Parmanent link": "パーマリンク",
+    "Page path and parmanent link": "ページ名とパーマリンク",
+    "Markdown link": "マークダウン形式のリンク"
+  },
+
   "search_help": {
   "search_help": {
     "title": "検索のヘルプ",
     "title": "検索のヘルプ",
     "and": {
     "and": {

+ 1 - 1
src/client/js/app.js

@@ -314,7 +314,7 @@ if (pageId) {
 }
 }
 if (pagePath) {
 if (pagePath) {
   componentMappings.page = <Page crowi={crowi} crowiRenderer={crowiRenderer} markdown={markdown} pagePath={pagePath} onSaveWithShortcut={saveWithShortcut} />;
   componentMappings.page = <Page crowi={crowi} crowiRenderer={crowiRenderer} markdown={markdown} pagePath={pagePath} onSaveWithShortcut={saveWithShortcut} />;
-  componentMappings['revision-path'] = <RevisionPath pagePath={pagePath} crowi={crowi} />;
+  componentMappings['revision-path'] = <I18nextProvider i18n={i18n}><RevisionPath pageId={pageId} pagePath={pagePath} crowi={crowi} /></I18nextProvider>;
   componentMappings['tag-label'] = <I18nextProvider i18n={i18n}><TagLabels crowi={crowi} pageId={pageId} sendTagData={setTagData} templateTagData={templateTagData} /></I18nextProvider>;
   componentMappings['tag-label'] = <I18nextProvider i18n={i18n}><TagLabels crowi={crowi} pageId={pageId} sendTagData={setTagData} templateTagData={templateTagData} /></I18nextProvider>;
 }
 }
 
 

+ 0 - 67
src/client/js/components/CopyButton.jsx

@@ -1,67 +0,0 @@
-import React from 'react';
-import PropTypes from 'prop-types';
-import ClipboardButton from 'react-clipboard.js';
-
-export default class CopyButton extends React.Component {
-
-  constructor(props) {
-    super(props);
-
-    this.showToolTip = this.showToolTip.bind(this);
-
-    // retrieve xss library from window
-    this.xss = window.xss;
-  }
-
-  showToolTip() {
-    const buttonId = `#${this.props.buttonId}`;
-    $(buttonId).tooltip('show');
-    setTimeout(() => {
-      $(buttonId).tooltip('hide');
-    }, 1000);
-  }
-
-  render() {
-    const containerStyle = {
-      lineHeight: 0,
-    };
-    const style = Object.assign({
-      padding: '0 2px',
-      verticalAlign: 'text-top',
-    }, this.props.buttonStyle);
-
-    const text = this.xss.process(this.props.text);
-
-    return (
-      <span className="btn-copy-container" style={containerStyle}>
-        <ClipboardButton
-          className={this.props.buttonClassName}
-          button-id={this.props.buttonId}
-          button-data-toggle="tooltip"
-          button-data-container="body"
-          button-title="copied!"
-          button-data-placement="bottom"
-          button-data-trigger="manual"
-          button-style={style}
-          data-clipboard-text={text}
-          onSuccess={this.showToolTip}
-        >
-
-          <i className={this.props.iconClassName} />
-        </ClipboardButton>
-      </span>
-    );
-  }
-
-}
-
-CopyButton.propTypes = {
-  text: PropTypes.string.isRequired,
-  buttonId: PropTypes.string.isRequired,
-  buttonClassName: PropTypes.string.isRequired,
-  buttonStyle: PropTypes.object,
-  iconClassName: PropTypes.string.isRequired,
-};
-CopyButton.defaultProps = {
-  buttonStyle: {},
-};

+ 118 - 0
src/client/js/components/Page/CopyDropdown.jsx

@@ -0,0 +1,118 @@
+import React from 'react';
+import PropTypes from 'prop-types';
+
+import Dropdown from 'react-bootstrap/es/Dropdown';
+import MenuItem from 'react-bootstrap/es/MenuItem';
+
+import { CopyToClipboard } from 'react-copy-to-clipboard';
+
+export default class CopyDropdown extends React.Component {
+
+  constructor(props) {
+    super(props);
+
+    // retrieve xss library from window
+    this.xss = window.xss;
+
+    this.generatePageUrl = this.generatePageUrl.bind(this);
+  }
+
+  showToolTip() {
+    const buttonId = '#copyPagePathDropdown';
+    $(buttonId).tooltip('show');
+    setTimeout(() => {
+      $(buttonId).tooltip('hide');
+    }, 1000);
+  }
+
+  generatePageUrl() {
+    return (this.props.pageId == null)
+      ? decodeURIComponent(window.location.pathname + window.location.search)
+      : `${window.location.origin}/${this.props.pageId}`;
+  }
+
+  generateMarkdownLink() {
+    return;
+  }
+
+  render() {
+    const { t } = this.props;
+
+    const safePagePath = this.xss.process(this.props.pagePath);
+    const url = this.generatePageUrl();
+
+    return (
+      <Dropdown id="copyPagePathDropdown">
+
+        <Dropdown.Toggle
+          className="btn-copy"
+          style={this.props.buttonStyle}
+          data-toggle="tooltip"
+          data-placement="bottom"
+          data-trigger="manual"
+          title="copied!"
+        >
+          <i className="ti-clipboard"></i>
+        </Dropdown.Toggle>
+
+        <Dropdown.Menu>
+          <h5 className="ml-3 my-0 text-muted">{ t('copy_to_clipboard.Copy to clipboard') }</h5>
+          <MenuItem divider></MenuItem>
+
+          {/* Page path */}
+          <CopyToClipboard text={this.props.pagePath} onCopy={this.showToolTip}>
+            <MenuItem>
+              <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>
+            </MenuItem>
+          </CopyToClipboard>
+          {/* Parmanent Link */}
+          { this.props.pageId && (
+            <CopyToClipboard text={url} onCopy={this.showToolTip}>
+              <MenuItem>
+                <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>
+              </MenuItem>
+            </CopyToClipboard>
+          )}
+          {/* Page path + Parmanent Link */}
+          { this.props.pageId && (
+            <CopyToClipboard text={`${this.props.pagePath}\n${url}`} onCopy={this.showToolTip}>
+              <MenuItem>
+                <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-1">{safePagePath}</span><br></br>
+                  <span className="small">{url}</span>
+                </div>
+              </MenuItem>
+            </CopyToClipboard>
+          )}
+          {/* Markdown Link */}
+          { this.props.pageId && (
+            <CopyToClipboard text={`[${this.props.pagePath}](${url})`} onCopy={this.showToolTip}>
+              <MenuItem>
+                <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>
+              </MenuItem>
+            </CopyToClipboard>
+          )}
+        </Dropdown.Menu>
+
+      </Dropdown>
+    );
+  }
+
+}
+
+CopyDropdown.propTypes = {
+  t: PropTypes.func.isRequired, // i18next
+  pagePath: PropTypes.string.isRequired,
+  pageId: PropTypes.string,
+  buttonStyle: PropTypes.object,
+};

+ 17 - 13
src/client/js/components/Page/RevisionPath.jsx

@@ -1,9 +1,11 @@
 import React from 'react';
 import React from 'react';
 import PropTypes from 'prop-types';
 import PropTypes from 'prop-types';
 
 
-import CopyButton from '../CopyButton';
+import { withTranslation } from 'react-i18next';
 
 
-export default class RevisionPath extends React.Component {
+import CopyDropdown from './CopyDropdown';
+
+class RevisionPath extends React.Component {
 
 
   constructor(props) {
   constructor(props) {
     super(props);
     super(props);
@@ -49,9 +51,10 @@ export default class RevisionPath extends React.Component {
   }
   }
 
 
   showToolTip() {
   showToolTip() {
-    $('#btnCopy').tooltip('show');
+    const buttonId = '#copyPagePathDropdown';
+    $(buttonId).tooltip('show');
     setTimeout(() => {
     setTimeout(() => {
-      $('#btnCopy').tooltip('hide');
+      $(buttonId).tooltip('hide');
     }, 1000);
     }, 1000);
   }
   }
 
 
@@ -78,7 +81,7 @@ export default class RevisionPath extends React.Component {
       marginLeft: '0.2em',
       marginLeft: '0.2em',
       marginRight: '0.2em',
       marginRight: '0.2em',
     };
     };
-    const editButtonStyle = {
+    const buttonStyle = {
       marginLeft: '0.5em',
       marginLeft: '0.5em',
       padding: '0 2px',
       padding: '0 2px',
     };
     };
@@ -110,13 +113,10 @@ export default class RevisionPath extends React.Component {
           <a href="/">/</a>
           <a href="/">/</a>
         </span>
         </span>
         {afterElements}
         {afterElements}
-        <CopyButton
-          buttonId="btnCopyRevisionPath"
-          text={this.props.pagePath}
-          buttonClassName="btn btn-default btn-copy"
-          iconClassName="ti-clipboard"
-        />
-        <a href="#edit" className="btn btn-default btn-edit" style={editButtonStyle}>
+
+        <CopyDropdown t={this.props.t} pagePath={this.props.pagePath} pageId={this.props.pageId} buttonStyle={buttonStyle}></CopyDropdown>
+
+        <a href="#edit" className="btn btn-default btn-edit" style={buttonStyle}>
           <i className="icon-note" />
           <i className="icon-note" />
         </a>
         </a>
       </span>
       </span>
@@ -126,6 +126,10 @@ export default class RevisionPath extends React.Component {
 }
 }
 
 
 RevisionPath.propTypes = {
 RevisionPath.propTypes = {
-  pagePath: PropTypes.string.isRequired,
+  t: PropTypes.func.isRequired, // i18next
   crowi: PropTypes.object.isRequired,
   crowi: PropTypes.object.isRequired,
+  pagePath: PropTypes.string.isRequired,
+  pageId: PropTypes.string,
 };
 };
+
+export default withTranslation()(RevisionPath);

+ 0 - 46
src/client/js/components/Page/RevisionUrl.js

@@ -1,46 +0,0 @@
-import React from 'react';
-import PropTypes from 'prop-types';
-
-import CopyButton from '../CopyButton';
-
-export default class RevisionUrl extends React.Component {
-
-  constructor(props) {
-    super(props);
-
-    // retrieve xss library from window
-    this.xss = window.xss;
-  }
-
-  render() {
-    const buttonStyle = {
-      fontSize: '1em',
-    };
-
-    const pagePath = this.xss.process(this.props.pagePath);
-
-    const url = (this.props.pageId == null)
-      ? decodeURIComponent(window.location.href)
-      : `${window.location.origin}/${this.props.pageId}`;
-    const copiedText = `${pagePath}\n${url}`;
-
-    return (
-      <span>
-        {url}
-        <CopyButton
-          buttonId="btnCopyRevisionUrl"
-          text={copiedText}
-          buttonClassName="btn btn-default btn-copy-link"
-          buttonStyle={buttonStyle}
-          iconClassName="ti-clipboard"
-        />
-      </span>
-    );
-  }
-
-}
-
-RevisionUrl.propTypes = {
-  pageId: PropTypes.string,
-  pagePath: PropTypes.string.isRequired,
-};

+ 12 - 12
src/client/js/components/PageEditor/CodeMirrorEditor.js

@@ -622,7 +622,7 @@ export default class CodeMirrorEditor extends AbstractEditor {
         title="Bold"
         title="Bold"
         onClick={this.createReplaceSelectionHandler('**', '**')}
         onClick={this.createReplaceSelectionHandler('**', '**')}
       >
       >
-        <img src="/images/icons/editor/bold.svg" alt="icon-bold" />
+        <img src="/images/icons/editor/bold.svg" alt="icon-bold" height="13" />
       </Button>,
       </Button>,
       <Button
       <Button
         key="nav-item-italic"
         key="nav-item-italic"
@@ -630,7 +630,7 @@ export default class CodeMirrorEditor extends AbstractEditor {
         title="Italic"
         title="Italic"
         onClick={this.createReplaceSelectionHandler('*', '*')}
         onClick={this.createReplaceSelectionHandler('*', '*')}
       >
       >
-        <img src="/images/icons/editor/italic.svg" alt="icon-italic" />
+        <img src="/images/icons/editor/italic.svg" alt="icon-italic" height="13" />
       </Button>,
       </Button>,
       <Button
       <Button
         key="nav-item-strikethrough"
         key="nav-item-strikethrough"
@@ -638,7 +638,7 @@ export default class CodeMirrorEditor extends AbstractEditor {
         title="Strikethrough"
         title="Strikethrough"
         onClick={this.createReplaceSelectionHandler('~~', '~~')}
         onClick={this.createReplaceSelectionHandler('~~', '~~')}
       >
       >
-        <img src="/images/icons/editor/strikethrough.svg" alt="icon-strikethrough" />
+        <img src="/images/icons/editor/strikethrough.svg" alt="icon-strikethrough" height="13" />
       </Button>,
       </Button>,
       <Button
       <Button
         key="nav-item-header"
         key="nav-item-header"
@@ -646,7 +646,7 @@ export default class CodeMirrorEditor extends AbstractEditor {
         title="Heading"
         title="Heading"
         onClick={this.makeHeaderHandler}
         onClick={this.makeHeaderHandler}
       >
       >
-        <img src="/images/icons/editor/header.svg" alt="icon-header" />
+        <img src="/images/icons/editor/header.svg" alt="icon-header" height="13" />
       </Button>,
       </Button>,
       <Button
       <Button
         key="nav-item-code"
         key="nav-item-code"
@@ -654,7 +654,7 @@ export default class CodeMirrorEditor extends AbstractEditor {
         title="Inline Code"
         title="Inline Code"
         onClick={this.createReplaceSelectionHandler('`', '`')}
         onClick={this.createReplaceSelectionHandler('`', '`')}
       >
       >
-        <img src="/images/icons/editor/code.svg" alt="icon-code" />
+        <img src="/images/icons/editor/code.svg" alt="icon-code" height="13" />
       </Button>,
       </Button>,
       <Button
       <Button
         key="nav-item-quote"
         key="nav-item-quote"
@@ -662,7 +662,7 @@ export default class CodeMirrorEditor extends AbstractEditor {
         title="Quote"
         title="Quote"
         onClick={this.createAddPrefixToEachLinesHandler('> ')}
         onClick={this.createAddPrefixToEachLinesHandler('> ')}
       >
       >
-        <img src="/images/icons/editor/quote.svg" alt="icon-quote" />
+        <img src="/images/icons/editor/quote.svg" alt="icon-quote" height="13" />
       </Button>,
       </Button>,
       <Button
       <Button
         key="nav-item-ul"
         key="nav-item-ul"
@@ -670,7 +670,7 @@ export default class CodeMirrorEditor extends AbstractEditor {
         title="List"
         title="List"
         onClick={this.createAddPrefixToEachLinesHandler('- ')}
         onClick={this.createAddPrefixToEachLinesHandler('- ')}
       >
       >
-        <img src="/images/icons/editor/list-ul.svg" alt="icon-list-ul" />
+        <img src="/images/icons/editor/list-ul.svg" alt="icon-list-ul" height="13" />
       </Button>,
       </Button>,
       <Button
       <Button
         key="nav-item-ol"
         key="nav-item-ol"
@@ -678,7 +678,7 @@ export default class CodeMirrorEditor extends AbstractEditor {
         title="Numbered List"
         title="Numbered List"
         onClick={this.createAddPrefixToEachLinesHandler('1. ')}
         onClick={this.createAddPrefixToEachLinesHandler('1. ')}
       >
       >
-        <img src="/images/icons/editor/list-ol.svg" alt="icon-list-ol" />
+        <img src="/images/icons/editor/list-ol.svg" alt="icon-list-ol" height="13" />
       </Button>,
       </Button>,
       <Button
       <Button
         key="nav-item-checkbox"
         key="nav-item-checkbox"
@@ -686,7 +686,7 @@ export default class CodeMirrorEditor extends AbstractEditor {
         title="Check List"
         title="Check List"
         onClick={this.createAddPrefixToEachLinesHandler('- [ ] ')}
         onClick={this.createAddPrefixToEachLinesHandler('- [ ] ')}
       >
       >
-        <img src="/images/icons/editor/check.svg" alt="icon-check" />
+        <img src="/images/icons/editor/check.svg" alt="icon-check" height="13" />
       </Button>,
       </Button>,
       <Button
       <Button
         key="nav-item-link"
         key="nav-item-link"
@@ -694,7 +694,7 @@ export default class CodeMirrorEditor extends AbstractEditor {
         title="Link"
         title="Link"
         onClick={this.createReplaceSelectionHandler('[', ']()')}
         onClick={this.createReplaceSelectionHandler('[', ']()')}
       >
       >
-        <img src="/images/icons/editor/link.svg" alt="icon-link" />
+        <img src="/images/icons/editor/link.svg" alt="icon-link" height="13" />
       </Button>,
       </Button>,
       <Button
       <Button
         key="nav-item-image"
         key="nav-item-image"
@@ -702,7 +702,7 @@ export default class CodeMirrorEditor extends AbstractEditor {
         title="Image"
         title="Image"
         onClick={this.createReplaceSelectionHandler('![', ']()')}
         onClick={this.createReplaceSelectionHandler('![', ']()')}
       >
       >
-        <img src="/images/icons/editor/picture.svg" alt="icon-picture" />
+        <img src="/images/icons/editor/picture.svg" alt="icon-picture" height="13" />
       </Button>,
       </Button>,
       <Button
       <Button
         key="nav-item-table"
         key="nav-item-table"
@@ -710,7 +710,7 @@ export default class CodeMirrorEditor extends AbstractEditor {
         title="Table"
         title="Table"
         onClick={this.showHandsonTableHandler}
         onClick={this.showHandsonTableHandler}
       >
       >
-        <img src="/images/icons/editor/table.svg" alt="icon-table" />
+        <img src="/images/icons/editor/table.svg" alt="icon-table" height="13" />
       </Button>,
       </Button>,
     ];
     ];
   }
   }

+ 1 - 4
src/client/styles/scss/_on-edit.scss

@@ -92,6 +92,7 @@ body.on-edit {
     left: $left-margin;
     left: $left-margin;
     z-index: 1;
     z-index: 1;
     width: calc(100% - #{$left-margin} - #{$right-margin});
     width: calc(100% - #{$left-margin} - #{$right-margin});
+    padding-top: 3px;
     pointer-events: none; // disable pointer-events because it becomes an obstacle
     pointer-events: none; // disable pointer-events because it becomes an obstacle
 
 
     background: none;
     background: none;
@@ -102,10 +103,6 @@ body.on-edit {
       pointer-events: initial; // enable pointer-events
       pointer-events: initial; // enable pointer-events
     }
     }
 
 
-    .header-wrap {
-      overflow-x: hidden;
-    }
-
     h1#revision-path {
     h1#revision-path {
       @include variable-font-size(20px);
       @include variable-font-size(20px);
       line-height: 1em;
       line-height: 1em;

+ 21 - 34
yarn.lock

@@ -2214,14 +2214,6 @@ cli@~1.0.1:
     exit "0.1.2"
     exit "0.1.2"
     glob "^7.1.1"
     glob "^7.1.1"
 
 
-clipboard@^2.0.0:
-  version "2.0.1"
-  resolved "https://registry.yarnpkg.com/clipboard/-/clipboard-2.0.1.tgz#a12481e1c13d8a50f5f036b0560fe5d16d74e46a"
-  dependencies:
-    good-listener "^1.2.2"
-    select "^1.1.2"
-    tiny-emitter "^2.0.0"
-
 cliui@^2.1.0:
 cliui@^2.1.0:
   version "2.1.0"
   version "2.1.0"
   resolved "https://registry.yarnpkg.com/cliui/-/cliui-2.1.0.tgz#4b475760ff80264c762c3a1719032e91c7fea0d1"
   resolved "https://registry.yarnpkg.com/cliui/-/cliui-2.1.0.tgz#4b475760ff80264c762c3a1719032e91c7fea0d1"
@@ -2554,6 +2546,13 @@ copy-descriptor@^0.1.0:
   version "0.1.1"
   version "0.1.1"
   resolved "https://registry.yarnpkg.com/copy-descriptor/-/copy-descriptor-0.1.1.tgz#676f6eb3c39997c2ee1ac3a924fd6124748f578d"
   resolved "https://registry.yarnpkg.com/copy-descriptor/-/copy-descriptor-0.1.1.tgz#676f6eb3c39997c2ee1ac3a924fd6124748f578d"
 
 
+copy-to-clipboard@^3:
+  version "3.2.0"
+  resolved "https://registry.yarnpkg.com/copy-to-clipboard/-/copy-to-clipboard-3.2.0.tgz#d2724a3ccbfed89706fac8a894872c979ac74467"
+  integrity sha512-eOZERzvCmxS8HWzugj4Uxl8OJxa7T2k1Gi0X5qavwydHIfuSHq2dTD09LOg/XyGq4Zpb5IsR/2OJ5lbOegz78w==
+  dependencies:
+    toggle-selection "^1.0.6"
+
 core-js@^1.0.0:
 core-js@^1.0.0:
   version "1.2.7"
   version "1.2.7"
   resolved "https://registry.yarnpkg.com/core-js/-/core-js-1.2.7.tgz#652294c14651db28fa93bd2d5ff2983a4f08c636"
   resolved "https://registry.yarnpkg.com/core-js/-/core-js-1.2.7.tgz#652294c14651db28fa93bd2d5ff2983a4f08c636"
@@ -3018,10 +3017,6 @@ delayed-stream@~1.0.0:
   version "1.0.0"
   version "1.0.0"
   resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619"
   resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619"
 
 
-delegate@^3.1.2:
-  version "3.2.0"
-  resolved "https://registry.yarnpkg.com/delegate/-/delegate-3.2.0.tgz#b66b71c3158522e8ab5744f720d8ca0c2af59166"
-
 delegates@^1.0.0:
 delegates@^1.0.0:
   version "1.0.0"
   version "1.0.0"
   resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a"
   resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a"
@@ -4632,12 +4627,6 @@ gonzales-pe@^4.0.3:
   dependencies:
   dependencies:
     minimist "1.1.x"
     minimist "1.1.x"
 
 
-good-listener@^1.2.2:
-  version "1.2.2"
-  resolved "https://registry.yarnpkg.com/good-listener/-/good-listener-1.2.2.tgz#d53b30cdf9313dffb7dc9a0d477096aa6d145c50"
-  dependencies:
-    delegate "^3.1.2"
-
 google-auth-library@^3.0.0:
 google-auth-library@^3.0.0:
   version "3.1.0"
   version "3.1.0"
   resolved "https://registry.yarnpkg.com/google-auth-library/-/google-auth-library-3.1.0.tgz#6378ea3e56067312209eee58223e5a00adaec639"
   resolved "https://registry.yarnpkg.com/google-auth-library/-/google-auth-library-3.1.0.tgz#6378ea3e56067312209eee58223e5a00adaec639"
@@ -8357,7 +8346,7 @@ prop-types@^15.0.0, prop-types@^15.6.2:
     loose-envify "^1.3.1"
     loose-envify "^1.3.1"
     object-assign "^4.1.1"
     object-assign "^4.1.1"
 
 
-prop-types@^15.5.0, prop-types@^15.5.10, prop-types@^15.5.8:
+prop-types@^15.5.10, prop-types@^15.5.8:
   version "15.6.0"
   version "15.6.0"
   resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.6.0.tgz#ceaf083022fc46b4a35f69e13ef75aed0d639856"
   resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.6.0.tgz#ceaf083022fc46b4a35f69e13ef75aed0d639856"
   dependencies:
   dependencies:
@@ -8593,18 +8582,19 @@ react-bootstrap@^0.32.1:
     uncontrollable "^4.1.0"
     uncontrollable "^4.1.0"
     warning "^3.0.0"
     warning "^3.0.0"
 
 
-react-clipboard.js@^2.0.0:
-  version "2.0.0"
-  resolved "https://registry.yarnpkg.com/react-clipboard.js/-/react-clipboard.js-2.0.0.tgz#8ab3c49093e73ea146eb3bbc054889b7a60bf2b4"
-  dependencies:
-    clipboard "^2.0.0"
-    prop-types "^15.5.0"
-
 react-codemirror2@^6.0.0:
 react-codemirror2@^6.0.0:
   version "6.0.0"
   version "6.0.0"
   resolved "https://registry.yarnpkg.com/react-codemirror2/-/react-codemirror2-6.0.0.tgz#180065df57a64026026cde569a9708fdf7656525"
   resolved "https://registry.yarnpkg.com/react-codemirror2/-/react-codemirror2-6.0.0.tgz#180065df57a64026026cde569a9708fdf7656525"
   integrity sha512-D7y9qZ05FbUh9blqECaJMdDwKluQiO3A9xB+fssd5jKM7YAXucRuEOlX32mJQumUvHUkHRHqXIPBjm6g0FW0Ag==
   integrity sha512-D7y9qZ05FbUh9blqECaJMdDwKluQiO3A9xB+fssd5jKM7YAXucRuEOlX32mJQumUvHUkHRHqXIPBjm6g0FW0Ag==
 
 
+react-copy-to-clipboard@^5.0.1:
+  version "5.0.1"
+  resolved "https://registry.yarnpkg.com/react-copy-to-clipboard/-/react-copy-to-clipboard-5.0.1.tgz#8eae107bb400be73132ed3b6a7b4fb156090208e"
+  integrity sha512-ELKq31/E3zjFs5rDWNCfFL4NvNFQvGRoJdAKReD/rUPA+xxiLPQmZBZBvy2vgH7V0GE9isIQpT9WXbwIVErYdA==
+  dependencies:
+    copy-to-clipboard "^3"
+    prop-types "^15.5.8"
+
 react-dom@^16.8.3:
 react-dom@^16.8.3:
   version "16.8.3"
   version "16.8.3"
   resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-16.8.3.tgz#ae236029e66210783ac81999d3015dfc475b9c32"
   resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-16.8.3.tgz#ae236029e66210783ac81999d3015dfc475b9c32"
@@ -9388,10 +9378,6 @@ scss-tokenizer@^0.2.3:
     js-base64 "^2.1.8"
     js-base64 "^2.1.8"
     source-map "^0.4.2"
     source-map "^0.4.2"
 
 
-select@^1.1.2:
-  version "1.1.2"
-  resolved "https://registry.yarnpkg.com/select/-/select-1.1.2.tgz#0e7350acdec80b1108528786ec1d4418d11b396d"
-
 semver-diff@^2.0.0:
 semver-diff@^2.0.0:
   version "2.1.0"
   version "2.1.0"
   resolved "https://registry.yarnpkg.com/semver-diff/-/semver-diff-2.1.0.tgz#4bbb8437c8d37e4b0cf1a68fd726ec6d645d6d36"
   resolved "https://registry.yarnpkg.com/semver-diff/-/semver-diff-2.1.0.tgz#4bbb8437c8d37e4b0cf1a68fd726ec6d645d6d36"
@@ -10479,10 +10465,6 @@ timsort@^0.3.0:
   version "0.3.0"
   version "0.3.0"
   resolved "https://registry.yarnpkg.com/timsort/-/timsort-0.3.0.tgz#405411a8e7e6339fe64db9a234de11dc31e02bd4"
   resolved "https://registry.yarnpkg.com/timsort/-/timsort-0.3.0.tgz#405411a8e7e6339fe64db9a234de11dc31e02bd4"
 
 
-tiny-emitter@^2.0.0:
-  version "2.0.2"
-  resolved "https://registry.yarnpkg.com/tiny-emitter/-/tiny-emitter-2.0.2.tgz#82d27468aca5ade8e5fd1e6d22b57dd43ebdfb7c"
-
 tmp@0.0.x, tmp@^0.0.33:
 tmp@0.0.x, tmp@^0.0.33:
   version "0.0.33"
   version "0.0.33"
   resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9"
   resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9"
@@ -10533,6 +10515,11 @@ toastr@^2.1.2:
   dependencies:
   dependencies:
     jquery ">=1.12.0"
     jquery ">=1.12.0"
 
 
+toggle-selection@^1.0.6:
+  version "1.0.6"
+  resolved "https://registry.yarnpkg.com/toggle-selection/-/toggle-selection-1.0.6.tgz#6e45b1263f2017fa0acc7d89d78b15b8bf77da32"
+  integrity sha1-bkWxJj8gF/oKzH2J14sVuL932jI=
+
 tough-cookie@~2.3.3:
 tough-cookie@~2.3.3:
   version "2.3.3"
   version "2.3.3"
   resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.3.3.tgz#0b618a5565b6dea90bf3425d04d55edc475a7561"
   resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.3.3.tgz#0b618a5565b6dea90bf3425d04d55edc475a7561"