mirror of
https://github.com/squidfunk/mkdocs-material.git
synced 2024-11-12 01:50:52 +01:00
Add clipboard.js support
This commit is contained in:
parent
adc98fac48
commit
4b6ffe6628
@ -407,16 +407,31 @@ extra:
|
||||
tabs: true
|
||||
```
|
||||
|
||||
### Clipboard.js Integration
|
||||
|
||||
Material supports [Clipboard.js][20] and will provide overlays on code blocks
|
||||
for easy copying. When mousing over a code block you will see a button in
|
||||
the upper right hand corner of the code. You can click the icon and have the
|
||||
entire content of the that code block copied to the clipboard without needing
|
||||
Flash. Clipboard.js support can be enabled by with the following settings:
|
||||
|
||||
```yaml
|
||||
extra_javascript:
|
||||
- https://cdnjs.cloudflare.com/ajax/libs/clipboard.js/1.6.1/clipboard.min.js
|
||||
```
|
||||
|
||||
[20]: https://clipboardjs.com/
|
||||
|
||||
### More advanced customization
|
||||
|
||||
If you want to change the general appearance of the Material theme, see
|
||||
[this article][20] for more information on advanced customization.
|
||||
[this article][21] for more information on advanced customization.
|
||||
|
||||
[20]: customization.md
|
||||
[21]: customization.md
|
||||
|
||||
## Extensions
|
||||
|
||||
MkDocs supports several [Markdown extensions][21]. The following extensions
|
||||
MkDocs supports several [Markdown extensions][22]. The following extensions
|
||||
are not enabled by default (see the link for which are enabled by default)
|
||||
but highly recommended, so they should be switched on at all times:
|
||||
|
||||
@ -430,20 +445,20 @@ markdown_extensions:
|
||||
For more information, see the following list of extensions supported by the
|
||||
Material theme including more information regarding installation and usage:
|
||||
|
||||
* [Admonition][22]
|
||||
* [Codehilite][23]
|
||||
* [Footnotes][24]
|
||||
* [Metadata][25]
|
||||
* [Permalinks][26]
|
||||
* [PyMdown Extensions][27]
|
||||
* [Admonition][23]
|
||||
* [Codehilite][24]
|
||||
* [Footnotes][25]
|
||||
* [Metadata][26]
|
||||
* [Permalinks][27]
|
||||
* [PyMdown Extensions][28]
|
||||
|
||||
[21]: http://www.mkdocs.org/user-guide/writing-your-docs/#markdown-extensions
|
||||
[22]: extensions/admonition.md
|
||||
[23]: extensions/codehilite.md
|
||||
[24]: extensions/footnotes.md
|
||||
[25]: extensions/metadata.md
|
||||
[26]: extensions/permalinks.md
|
||||
[27]: extensions/pymdown.md
|
||||
[22]: http://www.mkdocs.org/user-guide/writing-your-docs/#markdown-extensions
|
||||
[23]: extensions/admonition.md
|
||||
[24]: extensions/codehilite.md
|
||||
[25]: extensions/footnotes.md
|
||||
[26]: extensions/metadata.md
|
||||
[27]: extensions/permalinks.md
|
||||
[28]: extensions/pymdown.md
|
||||
|
||||
## Full example
|
||||
|
||||
@ -493,4 +508,8 @@ markdown_extensions:
|
||||
- admonition
|
||||
- codehilite(guess_lang=false)
|
||||
- toc(permalink=true)
|
||||
|
||||
# CSS
|
||||
extra_javascript:
|
||||
- https://cdnjs.cloudflare.com/ajax/libs/clipboard.js/1.6.0/clipboard.min.js
|
||||
```
|
||||
|
File diff suppressed because one or more lines are too long
3
material/assets/javascripts/application-876a5cae0c.js
Normal file
3
material/assets/javascripts/application-876a5cae0c.js
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
1
material/assets/stylesheets/application-99e13a48f0.css
Normal file
1
material/assets/stylesheets/application-99e13a48f0.css
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -38,9 +38,9 @@
|
||||
<script src="{{ base_url }}/assets/javascripts/modernizr-56ade86843.js"></script>
|
||||
{% endblock %}
|
||||
{% block styles %}
|
||||
<link rel="stylesheet" href="{{ base_url }}/assets/stylesheets/application-e2807e330f.css">
|
||||
<link rel="stylesheet" href="{{ base_url }}/assets/stylesheets/application-99e13a48f0.css">
|
||||
{% if config.extra.palette %}
|
||||
<link rel="stylesheet" href="{{ base_url }}/assets/stylesheets/application-f78e5cb881.palette.css">
|
||||
<link rel="stylesheet" href="{{ base_url }}/assets/stylesheets/application-0a3e9e1c07.palette.css">
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
{% block fonts %}
|
||||
@ -149,7 +149,7 @@
|
||||
{% endblock %}
|
||||
</div>
|
||||
{% block scripts %}
|
||||
<script src="{{ base_url }}/assets/javascripts/application-6b599127bc.js"></script>
|
||||
<script src="{{ base_url }}/assets/javascripts/application-876a5cae0c.js"></script>
|
||||
<script>app.initialize({url:{base:"{{ base_url }}"}})</script>
|
||||
{% for path in extra_javascript %}
|
||||
<script src="{{ path }}"></script>
|
||||
|
@ -94,3 +94,6 @@ pages:
|
||||
google_analytics:
|
||||
- !!python/object/apply:os.getenv ["GOOGLE_ANALYTICS_KEY"]
|
||||
- auto
|
||||
|
||||
extra_javascript:
|
||||
- https://cdnjs.cloudflare.com/ajax/libs/clipboard.js/1.6.1/clipboard.min.js
|
||||
|
@ -81,6 +81,47 @@ function initialize(config) { // eslint-disable-line func-style
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
/* If Clipboard.js is available, inject "copy to clipboard" overlays
|
||||
and attach Clipboard to copy the code.
|
||||
Handle both div.codehilite>pre and pre>code. */
|
||||
// $FlowFixMe
|
||||
if (typeof Clipboard !== "undefined" &&
|
||||
Clipboard.isSupported()) { // eslint-disable-line no-undef
|
||||
const blocks = document.querySelectorAll(
|
||||
"div.codehilite>pre,pre.codehilite>code")
|
||||
let i = 0
|
||||
Array.prototype.forEach.call(blocks, code => {
|
||||
const parent = code.parentNode
|
||||
const codeId = `hl_code${i}`
|
||||
const btn = document.createElement("button")
|
||||
const icon = document.createElement("i")
|
||||
parent.id = codeId
|
||||
icon.setAttribute("class", "md-icon md-icon--clipboard")
|
||||
btn.appendChild(icon)
|
||||
btn.setAttribute("class", "clip-btn")
|
||||
btn.setAttribute("data-clipboard-target",
|
||||
`#${codeId} pre, #${codeId} code`)
|
||||
btn.setAttribute("aria-label", "Copy to Clipboard.")
|
||||
new Material.Event.Listener(btn, "mouseleave", e => {
|
||||
e.currentTarget.setAttribute("class","clip-btn")
|
||||
e.currentTarget.setAttribute("aria-label", "Copy to Clipboard.")
|
||||
}).listen()
|
||||
parent.insertBefore(btn, parent.childNodes[0])
|
||||
i += 1
|
||||
})
|
||||
const cBoard = new Clipboard(".clip-btn") // eslint-disable-line no-undef
|
||||
cBoard.on("success", e => {
|
||||
e.clearSelection()
|
||||
e.trigger.setAttribute("aria-label", "Copied!")
|
||||
e.trigger.setAttribute("class", "clip-btn clip-tip")
|
||||
})
|
||||
cBoard.on("error", e => {
|
||||
e.clearSelection()
|
||||
e.trigger.setAttribute("aria-label", "Copy Failed!")
|
||||
e.trigger.setAttribute("class", "clip-btn clip-tip")
|
||||
})
|
||||
}
|
||||
}).listen()
|
||||
|
||||
/* Component: header shadow toggle */
|
||||
|
@ -103,6 +103,11 @@ button[data-md-color-accent] {
|
||||
background-color: $color;
|
||||
}
|
||||
|
||||
// Copy to clipboard button overlay.
|
||||
.codehilite:hover .clip-btn:hover {
|
||||
background-color: $color;
|
||||
}
|
||||
|
||||
// Current or hovered link
|
||||
.md-nav__link:active,
|
||||
.md-nav__item--active > .md-nav__link {
|
||||
|
@ -56,6 +56,8 @@
|
||||
@import "extensions/footnotes";
|
||||
@import "extensions/permalinks";
|
||||
|
||||
@import "clipboardjs/clipboardjs";
|
||||
|
||||
@import "extensions/pymdown/arithmatex";
|
||||
@import "extensions/pymdown/critic";
|
||||
@import "extensions/pymdown/emoji";
|
||||
|
@ -57,7 +57,8 @@
|
||||
"arrow_forward": "arrow-forward",
|
||||
"menu": "menu",
|
||||
"search": "search",
|
||||
"school": "home"
|
||||
"school": "home",
|
||||
"assignment": "clipboard"
|
||||
) {
|
||||
&--#{$name}::before {
|
||||
content: $ligature;
|
||||
|
104
src/assets/stylesheets/clipboardjs/_clipboardjs.scss
Normal file
104
src/assets/stylesheets/clipboardjs/_clipboardjs.scss
Normal file
@ -0,0 +1,104 @@
|
||||
////
|
||||
/// Copyright (c) 2016-2017 Martin Donath <martin.donath@squidfunk.com>
|
||||
///
|
||||
/// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
/// copy of this software and associated documentation files (the "Software"),
|
||||
/// to deal in the Software without restriction, including without limitation
|
||||
/// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
/// and/or sell copies of the Software, and to permit persons to whom the
|
||||
/// Software is furnished to do so, subject to the following conditions:
|
||||
///
|
||||
/// The above copyright notice and this permission notice shall be included in
|
||||
/// all copies or substantial portions of the Software.
|
||||
///
|
||||
/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
|
||||
/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
/// DEALINGS
|
||||
////
|
||||
|
||||
$clip-btn-background: #C4C4C4;
|
||||
$clip-tip-background: #404040;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Rules
|
||||
// ----------------------------------------------------------------------------
|
||||
.md-typeset {
|
||||
|
||||
// Render muted when hovering over code and
|
||||
// render fully when hovering over the button.
|
||||
.codehilite {
|
||||
&:hover {
|
||||
.clip-btn {
|
||||
transition: opacity 0.3s;
|
||||
opacity: 0.4;
|
||||
|
||||
&:hover {
|
||||
transition: opacity 0.1s;
|
||||
background-color: $md-color-primary;
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Clipboard button object.
|
||||
.clip-btn {
|
||||
@include z-depth(2);
|
||||
|
||||
display: inline-block;
|
||||
position: absolute;
|
||||
top: 0.2rem;
|
||||
right: 0.2rem;
|
||||
width: 3.2rem;
|
||||
height: 3.2rem;
|
||||
transition: opacity 0.3s;
|
||||
border-radius: 50%;
|
||||
background-color: $clip-btn-background;
|
||||
color: $md-color-white;
|
||||
cursor: pointer;
|
||||
opacity: 0;
|
||||
overflow: visible;
|
||||
|
||||
.md-icon--clipboard {
|
||||
position: relative;
|
||||
top: 0.1rem;
|
||||
font-size: 1.8rem;
|
||||
}
|
||||
}
|
||||
|
||||
// Tooltips for messages when a copy is successful or fails.
|
||||
// Render it to the left as somtimes it is in a code table which
|
||||
// cuts off the right, or on the edge of the screen with mobile.
|
||||
.clip-tip {
|
||||
&::after {
|
||||
position: absolute;
|
||||
top: 0.3rem;
|
||||
left: 0;
|
||||
padding: 0.6rem 1rem;
|
||||
transform: translateX(-112%) translateY(0);
|
||||
transition: opacity 0.2s;
|
||||
border-radius: 0.2rem;
|
||||
background: $clip-tip-background;
|
||||
color: $md-color-white;
|
||||
font-size: ms(-1);
|
||||
font-weight: 700;
|
||||
white-space: nowrap;
|
||||
content: attr(aria-label);
|
||||
opacity: 1;
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
&::after {
|
||||
display: block;
|
||||
transform: translateX(-110%) translateY(0);
|
||||
opacity: 0.9;
|
||||
visibility: visible;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -216,15 +216,23 @@ $codehilite-whitespace: transparent;
|
||||
// If code blocks are wrapped with codehilite, the styles must be adjusted
|
||||
// so the marker stretches to the whole width and the padding is respected
|
||||
.codehilite {
|
||||
position: relative;
|
||||
margin: 1em 0;
|
||||
padding: 1rem 1.2rem 0.8rem;
|
||||
padding: 0;
|
||||
border-radius: 0.2rem;
|
||||
background-color: $md-code-background;
|
||||
color: $md-code-color;
|
||||
line-height: 1.4;
|
||||
overflow: auto;
|
||||
overflow: visible;
|
||||
-webkit-overflow-scrolling: touch;
|
||||
|
||||
// Avoid current behaviour where all '[id]:before' are
|
||||
// 'display: inline-block'. This becomes a problem when clipboard overlay
|
||||
// is applied.
|
||||
&[id]::before {
|
||||
display: inline;
|
||||
}
|
||||
|
||||
// Override native scrollbar styles
|
||||
&::-webkit-scrollbar {
|
||||
width: 0.4rem;
|
||||
@ -241,19 +249,27 @@ $codehilite-whitespace: transparent;
|
||||
}
|
||||
}
|
||||
|
||||
// Hack: set pre-tag to inline-block, in order to stetch the content on
|
||||
// overflow correctly to the whole width
|
||||
pre {
|
||||
display: inline-block;
|
||||
min-width: 100%;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
padding: 1rem 1.2rem 0.8rem;
|
||||
background-color: transparent;
|
||||
overflow: visible;
|
||||
overflow: auto;
|
||||
vertical-align: top;
|
||||
}
|
||||
}
|
||||
|
||||
// If not using Pygments, code will be under pre>code
|
||||
pre.codehilite {
|
||||
overflow: visible;
|
||||
|
||||
code {
|
||||
display: block;
|
||||
padding: 1rem 1.2rem 0.8rem;
|
||||
overflow: auto;
|
||||
}
|
||||
}
|
||||
|
||||
// Block with line numbers
|
||||
.codehilitetable {
|
||||
display: block;
|
||||
|
@ -277,7 +277,7 @@
|
||||
{% block scripts %}
|
||||
<script src="{{ base_url }}/assets/javascripts/application.js"></script>
|
||||
<script>
|
||||
app.initialize({ url: { base: "{{ base_url }}", } });
|
||||
app.initialize({ url: { base: "{{ base_url }}" } });
|
||||
</script>
|
||||
{% for path in extra_javascript %}
|
||||
<script src="{{ path }}"></script>
|
||||
|
Loading…
Reference in New Issue
Block a user