Add clipboard.js support

This commit is contained in:
facelessuser 2017-05-15 18:31:10 -06:00
parent adc98fac48
commit 4b6ffe6628
16 changed files with 224 additions and 33 deletions

View File

@ -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

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

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -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>

View File

@ -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

View File

@ -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 */

View File

@ -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 {

View File

@ -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";

View File

@ -57,7 +57,8 @@
"arrow_forward": "arrow-forward",
"menu": "menu",
"search": "search",
"school": "home"
"school": "home",
"assignment": "clipboard"
) {
&--#{$name}::before {
content: $ligature;

View 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;
}
}
}
}

View File

@ -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;

View File

@ -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>