hdoc-tools 0.62.3 → 0.62.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/hdoc-install-browser.js +24 -0
- package/hdoc-validate-interbook.js +8 -0
- package/hdoc-validate.js +92 -35
- package/package.json +1 -1
- package/templates/pdf/css/hdocs-pdf.css +17 -0
- package/templates/pdf/template.html +6 -0
- package/ui/css/theme-default/styles/components/content.css +11 -8
- package/ui/js/highlightjs-badge.js +56 -28
package/hdoc-install-browser.js
CHANGED
|
@@ -61,6 +61,30 @@
|
|
|
61
61
|
|
|
62
62
|
const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
63
63
|
|
|
64
|
+
// @puppeteer/browsers mkdirs <cacheDir>/<browser> non-recursively, so the
|
|
65
|
+
// cache dir must exist first — on a fresh checkout it does not. A dangling
|
|
66
|
+
// symlink (e.g. left behind after the package dir it pointed at was removed)
|
|
67
|
+
// is worse: mkdir through it fails ENOENT forever, so drop it first.
|
|
68
|
+
try {
|
|
69
|
+
fs.lstatSync(cacheDir);
|
|
70
|
+
try {
|
|
71
|
+
fs.statSync(cacheDir); // resolves the link target
|
|
72
|
+
} catch {
|
|
73
|
+
log(`Removing dangling cache dir link: ${cacheDir}`);
|
|
74
|
+
fs.unlinkSync(cacheDir);
|
|
75
|
+
}
|
|
76
|
+
} catch {
|
|
77
|
+
/* nothing there yet */
|
|
78
|
+
}
|
|
79
|
+
try {
|
|
80
|
+
fs.mkdirSync(cacheDir, { recursive: true });
|
|
81
|
+
} catch (err) {
|
|
82
|
+
console.error(
|
|
83
|
+
`${RED}Unable to create browser cache dir ${cacheDir}: ${err.message}${RESET}`,
|
|
84
|
+
);
|
|
85
|
+
process.exit(1);
|
|
86
|
+
}
|
|
87
|
+
|
|
64
88
|
const rmrf = (target) => {
|
|
65
89
|
try {
|
|
66
90
|
fs.rmSync(target, { recursive: true, force: true });
|
|
@@ -290,6 +290,14 @@
|
|
|
290
290
|
const doc_id = segments.shift();
|
|
291
291
|
const article_path = segments.length > 0 ? segments.join("/") : "index";
|
|
292
292
|
|
|
293
|
+
// No book in the path (e.g. a bare "/") - nothing to resolve
|
|
294
|
+
if (!doc_id) {
|
|
295
|
+
return {
|
|
296
|
+
level: "skip",
|
|
297
|
+
message: `Inter-book link has no target book - link not verified: ${link}`,
|
|
298
|
+
};
|
|
299
|
+
}
|
|
300
|
+
|
|
293
301
|
// Books not sourced from GitHub — resolved by docId suffix, no repo
|
|
294
302
|
if (has_suffix(doc_id, UNVERIFIABLE_SUFFIXES)) {
|
|
295
303
|
return {
|
package/hdoc-validate.js
CHANGED
|
@@ -498,10 +498,22 @@
|
|
|
498
498
|
return resp.status;
|
|
499
499
|
};
|
|
500
500
|
|
|
501
|
-
//
|
|
502
|
-
//
|
|
503
|
-
|
|
504
|
-
const
|
|
501
|
+
// Links already written to validated-links.txt this run. A link can appear
|
|
502
|
+
// on many pages, but only needs writing to the cache file once.
|
|
503
|
+
const skip_links_written = new Set();
|
|
504
|
+
const appendSkipLink = (link) => {
|
|
505
|
+
if (skip_links_written.has(link)) return;
|
|
506
|
+
skip_links_written.add(link);
|
|
507
|
+
fs.appendFileSync(skip_link_file, `${link}\n`);
|
|
508
|
+
};
|
|
509
|
+
|
|
510
|
+
// Map a network check result (inter-book or external URL) onto
|
|
511
|
+
// errors/warnings/messages and the validated-links cache. 'ok' and 'skip'
|
|
512
|
+
// outcomes are stable, so they are appended to validated-links.txt like any
|
|
513
|
+
// other passing link. Called once per PAGE carrying the link, so the
|
|
514
|
+
// message is positioned against the page being reported on.
|
|
515
|
+
const emitLinkResult = (result, link, htmlFile, markdown_paths, markdown_content) => {
|
|
516
|
+
if (!result) return;
|
|
505
517
|
if (result.level === "error") {
|
|
506
518
|
errors[htmlFile.relativePath].push(
|
|
507
519
|
processErrorMessage(result.message, markdown_paths.relativePath, markdown_content, link),
|
|
@@ -512,10 +524,25 @@
|
|
|
512
524
|
);
|
|
513
525
|
} else {
|
|
514
526
|
messages[htmlFile.relativePath].push(result.message);
|
|
515
|
-
|
|
527
|
+
appendSkipLink(link);
|
|
516
528
|
}
|
|
517
529
|
};
|
|
518
530
|
|
|
531
|
+
// Run a network check for a link at most once per run, but hand the SAME
|
|
532
|
+
// result back to every page that carries the link. Deduplicating the fetch
|
|
533
|
+
// is a performance concern; deduplicating the reporting is not - a broken
|
|
534
|
+
// link on ten pages has to be flagged on all ten, or fixing the first page
|
|
535
|
+
// just surfaces the second on the next build.
|
|
536
|
+
// global_links_checked: Map link -> Promise<{ level, message } | null>
|
|
537
|
+
const checkLinkOnce = (global_links_checked, link, check) => {
|
|
538
|
+
let pending = global_links_checked.get(link);
|
|
539
|
+
if (!pending) {
|
|
540
|
+
pending = check();
|
|
541
|
+
global_links_checked.set(link, pending);
|
|
542
|
+
}
|
|
543
|
+
return pending;
|
|
544
|
+
};
|
|
545
|
+
|
|
519
546
|
const checkLinks = async (source_path, htmlFile, links, hdocbook_config, hdocbook_project, global_links_checked, output_links) => {
|
|
520
547
|
const markdown_paths = getMDPathFromHtmlPath(htmlFile);
|
|
521
548
|
const markdown_content = fs.readFileSync(markdown_paths.markdownPath, 'utf8');
|
|
@@ -537,11 +564,15 @@
|
|
|
537
564
|
// concurrently rather than one-at-a-time.
|
|
538
565
|
const externalChecks = [];
|
|
539
566
|
|
|
567
|
+
// Same link twice on the same page is reported once. Across pages it is
|
|
568
|
+
// reported every time - see checkLinkOnce.
|
|
569
|
+
const page_links_checked = new Set();
|
|
570
|
+
|
|
540
571
|
for (let i = 0; i < links.length; i++) {
|
|
541
572
|
if (output_links) console.log(` - ${links[i]}`);
|
|
542
573
|
if (exclude_links[links[i]]) continue;
|
|
543
|
-
if (
|
|
544
|
-
|
|
574
|
+
if (page_links_checked.has(links[i])) continue;
|
|
575
|
+
page_links_checked.add(links[i]);
|
|
545
576
|
|
|
546
577
|
const valid_url = hdoc.valid_url(links[i]);
|
|
547
578
|
if (!valid_url) {
|
|
@@ -554,6 +585,13 @@
|
|
|
554
585
|
if (link_segments[0] === "") link_segments.shift();
|
|
555
586
|
const link_root = link_segments[0] === "_books" ? link_segments[1] : link_segments[0];
|
|
556
587
|
|
|
588
|
+
// A bare "/" is the docs site home page - no book, nothing to
|
|
589
|
+
// resolve locally or against GitHub.
|
|
590
|
+
if (link_root === undefined || link_root === "") {
|
|
591
|
+
appendSkipLink(links[i]);
|
|
592
|
+
continue;
|
|
593
|
+
}
|
|
594
|
+
|
|
557
595
|
// Check for links with a _books path that have no specific file target
|
|
558
596
|
// We do need to exclude those with an extension though, for pages that link downloadable resources
|
|
559
597
|
if (link_segments[0] === "_books" && path.extname(links[i]) === '') {
|
|
@@ -567,8 +605,10 @@
|
|
|
567
605
|
if (interbook.enabled() && path.extname(links[i].split("#")[0]) === "") {
|
|
568
606
|
const link = links[i];
|
|
569
607
|
externalChecks.push(async () =>
|
|
570
|
-
|
|
571
|
-
await
|
|
608
|
+
emitLinkResult(
|
|
609
|
+
await checkLinkOnce(global_links_checked, link, () =>
|
|
610
|
+
interbook.check_link(link),
|
|
611
|
+
),
|
|
572
612
|
link,
|
|
573
613
|
htmlFile,
|
|
574
614
|
markdown_paths,
|
|
@@ -576,7 +616,7 @@
|
|
|
576
616
|
),
|
|
577
617
|
);
|
|
578
618
|
} else {
|
|
579
|
-
|
|
619
|
+
appendSkipLink(links[i]);
|
|
580
620
|
}
|
|
581
621
|
continue;
|
|
582
622
|
}
|
|
@@ -603,12 +643,12 @@
|
|
|
603
643
|
)
|
|
604
644
|
.edit_path.replace(path.extname(htmlFile.relativePath), ".md")
|
|
605
645
|
) {
|
|
606
|
-
|
|
646
|
+
appendSkipLink(links[i]);
|
|
607
647
|
continue;
|
|
608
648
|
}
|
|
609
649
|
|
|
610
650
|
if (valid_url.protocol === "mailto:") {
|
|
611
|
-
|
|
651
|
+
appendSkipLink(links[i]);
|
|
612
652
|
continue;
|
|
613
653
|
}
|
|
614
654
|
|
|
@@ -653,8 +693,10 @@
|
|
|
653
693
|
const link = links[i];
|
|
654
694
|
const book_link = valid_url.pathname + valid_url.hash;
|
|
655
695
|
externalChecks.push(async () =>
|
|
656
|
-
|
|
657
|
-
await
|
|
696
|
+
emitLinkResult(
|
|
697
|
+
await checkLinkOnce(global_links_checked, link, () =>
|
|
698
|
+
interbook.check_link(book_link),
|
|
699
|
+
),
|
|
658
700
|
link,
|
|
659
701
|
htmlFile,
|
|
660
702
|
markdown_paths,
|
|
@@ -668,20 +710,19 @@
|
|
|
668
710
|
const url = links[i];
|
|
669
711
|
const isInternal = url.toLowerCase().includes("internal.hornbill.com");
|
|
670
712
|
|
|
671
|
-
|
|
713
|
+
// Returns a page-independent { level, message } (or null for "say
|
|
714
|
+
// nothing") so the outcome can be cached per URL and replayed
|
|
715
|
+
// against every page that links to it.
|
|
716
|
+
const checkExternalUrl = async () => {
|
|
672
717
|
// For internal.hornbill.com links, check network reachability first (result cached)
|
|
673
718
|
if (isInternal) {
|
|
674
719
|
const on_int_net = await ensureIntNetCached();
|
|
675
720
|
if (!on_int_net) {
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
return;
|
|
721
|
+
return {
|
|
722
|
+
level: "skip",
|
|
723
|
+
message: `Outside of Hornbill network - skipping internal link validation for: ${url}`,
|
|
724
|
+
};
|
|
681
725
|
}
|
|
682
|
-
messages[htmlFile.relativePath].push(
|
|
683
|
-
`Inside of Hornbill network - performing internal link validation for: ${url}`,
|
|
684
|
-
);
|
|
685
726
|
}
|
|
686
727
|
|
|
687
728
|
try {
|
|
@@ -689,25 +730,39 @@
|
|
|
689
730
|
if ((status < 200 || status > 299) && status !== 304) {
|
|
690
731
|
if (process.env.GITHUB_ACTIONS === 'true' && status === 403 && url.includes(".hornbill.com")) {
|
|
691
732
|
// Always returns 403 for Hornbill sites through GitHub Actions — not a real error
|
|
692
|
-
|
|
693
|
-
throw `Unexpected Status Returned: ${status}`;
|
|
733
|
+
return null;
|
|
694
734
|
}
|
|
695
|
-
|
|
696
|
-
fs.appendFileSync(skip_link_file, `${url}\n`);
|
|
735
|
+
throw `Unexpected Status Returned: ${status}`;
|
|
697
736
|
}
|
|
737
|
+
return {
|
|
738
|
+
level: "ok",
|
|
739
|
+
message: `External link is valid: ${url}`,
|
|
740
|
+
};
|
|
698
741
|
} catch (e) {
|
|
699
742
|
let error_message;
|
|
700
743
|
if (e instanceof AggregateError) {
|
|
701
|
-
error_message =
|
|
744
|
+
error_message = `Issue with external link [${url}]: ${e.message} - ${JSON.stringify(e.errors)}`;
|
|
702
745
|
} else {
|
|
703
|
-
error_message =
|
|
746
|
+
error_message = `Issue with external link [${url}]: ${e}`;
|
|
704
747
|
}
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
748
|
+
const level =
|
|
749
|
+
hdocbook_project.validation.external_link_warnings ||
|
|
750
|
+
process.env.GITHUB_ACTIONS === 'true'
|
|
751
|
+
? "warning"
|
|
752
|
+
: "error";
|
|
753
|
+
return { level, message: error_message };
|
|
709
754
|
}
|
|
710
|
-
}
|
|
755
|
+
};
|
|
756
|
+
|
|
757
|
+
externalChecks.push(async () =>
|
|
758
|
+
emitLinkResult(
|
|
759
|
+
await checkLinkOnce(global_links_checked, url, checkExternalUrl),
|
|
760
|
+
url,
|
|
761
|
+
htmlFile,
|
|
762
|
+
markdown_paths,
|
|
763
|
+
markdown_content,
|
|
764
|
+
),
|
|
765
|
+
);
|
|
711
766
|
}
|
|
712
767
|
}
|
|
713
768
|
|
|
@@ -1136,7 +1191,9 @@
|
|
|
1136
1191
|
}
|
|
1137
1192
|
|
|
1138
1193
|
|
|
1139
|
-
|
|
1194
|
+
// link -> Promise<{ level, message } | null> for network checks: fetched
|
|
1195
|
+
// once per run, but reported on every page that carries the link.
|
|
1196
|
+
const global_links_checked = new Map();
|
|
1140
1197
|
|
|
1141
1198
|
for (const key in html_to_validate) {
|
|
1142
1199
|
const file = html_to_validate[key];
|
package/package.json
CHANGED
|
@@ -462,6 +462,23 @@ code {
|
|
|
462
462
|
font-size: 0.9em;
|
|
463
463
|
}
|
|
464
464
|
|
|
465
|
+
/* A PDF page cannot be scrolled, so a code block that overflows its box is
|
|
466
|
+
simply clipped at the page edge and the rest of the line is lost. Wrap
|
|
467
|
+
instead: pre-wrap keeps the authored newlines/indentation while allowing
|
|
468
|
+
long lines (curl one-liners, long endpoint URLs) to break. anywhere is
|
|
469
|
+
needed because break-word will not split an unbroken token such as a URL
|
|
470
|
+
or a base64 blob. .hljs is included because the highlight.js theme sets
|
|
471
|
+
overflow-x: auto on it, which is meaningless in print. */
|
|
472
|
+
pre,
|
|
473
|
+
pre code,
|
|
474
|
+
.hljs {
|
|
475
|
+
white-space: pre-wrap;
|
|
476
|
+
overflow-wrap: anywhere;
|
|
477
|
+
word-break: normal;
|
|
478
|
+
overflow-x: visible;
|
|
479
|
+
max-width: 100%;
|
|
480
|
+
}
|
|
481
|
+
|
|
465
482
|
/* From Bootstrap 5, text color decorations */
|
|
466
483
|
.text-primary {
|
|
467
484
|
color: #0d6efd !important;
|
|
@@ -6,6 +6,12 @@
|
|
|
6
6
|
<link rel="stylesheet"
|
|
7
7
|
href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.7.0/styles/base16/humanoid-light.min.css">
|
|
8
8
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.7.0/highlight.min.js"></script>
|
|
9
|
+
<!-- highlight.min.js is the "common" bundle only (~37 languages) and does NOT
|
|
10
|
+
include PowerShell, so language-powershell blocks rendered as plain black
|
|
11
|
+
text in PDFs while go/js/php/python/sh (all common) were coloured.
|
|
12
|
+
Register the extra grammar explicitly - keep the version in lockstep with
|
|
13
|
+
the core bundle above. -->
|
|
14
|
+
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.7.0/languages/powershell.min.js"></script>
|
|
9
15
|
</head>
|
|
10
16
|
|
|
11
17
|
<body>
|
|
@@ -13,9 +13,15 @@
|
|
|
13
13
|
position:relative;
|
|
14
14
|
}
|
|
15
15
|
|
|
16
|
+
/* The container is a flex row holding the content pane and the TOC. The
|
|
17
|
+
content pane does all the flexing (basis 0, min-width 0 so wide content -
|
|
18
|
+
tables, code blocks - cannot force it wider); the TOC keeps a fixed,
|
|
19
|
+
non-shrinking basis. Giving both children a width made the row
|
|
20
|
+
over-committed, so both shrank pro-rata and the TOC collapsed to ~118px. */
|
|
16
21
|
.DocContent .injected-document-content
|
|
17
22
|
{
|
|
18
|
-
|
|
23
|
+
flex: 1 1 0;
|
|
24
|
+
min-width: 0;
|
|
19
25
|
}
|
|
20
26
|
|
|
21
27
|
.DocContent .injected-document-toc
|
|
@@ -23,7 +29,7 @@
|
|
|
23
29
|
height: fit-content;
|
|
24
30
|
display:none;
|
|
25
31
|
margin:0 0 0 50px;
|
|
26
|
-
|
|
32
|
+
flex: 0 0 clamp(260px, 26%, 400px);
|
|
27
33
|
}
|
|
28
34
|
|
|
29
35
|
.DocContent .injected-document-toc .H2{
|
|
@@ -87,12 +93,9 @@
|
|
|
87
93
|
display:inline-block;
|
|
88
94
|
}
|
|
89
95
|
|
|
90
|
-
/*
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
width: 900px;
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
+
/* Room for the TOC comes from its own flex basis now - a width here would be
|
|
97
|
+
ignored anyway (flex-basis 0 on the content pane wins over width). */
|
|
98
|
+
|
|
96
99
|
}
|
|
97
100
|
|
|
98
101
|
/* style overrides to apply on screens that are 1920px and wider */
|
|
@@ -93,6 +93,33 @@ Uses some ES6 features so won't work in IE without shims:
|
|
|
93
93
|
if (typeof highlightJsBadgeAutoLoad !== 'boolean')
|
|
94
94
|
var highlightJsBadgeAutoLoad = false;
|
|
95
95
|
|
|
96
|
+
//-- LOCAL FIX: display names for the badge label, so a fence written as ```md shows "Markdown".
|
|
97
|
+
//-- highlight.js 11 grammars carry a cased `name` and are preferred when present, but the pack
|
|
98
|
+
//-- vendored here is a v9 build whose grammars have aliases and no name at all - hence this
|
|
99
|
+
//-- table. Keyed by alias as well as canonical name, because the badge label is whatever the
|
|
100
|
+
//-- author typed in the fence. Anything missing falls through and displays unchanged.
|
|
101
|
+
var HDOC_LANG_DISPLAY_NAMES = {
|
|
102
|
+
apache: "Apache", apacheconf: "Apache",
|
|
103
|
+
bash: "Bash", sh: "Bash", zsh: "Bash", shell: "Shell", console: "Shell Session",
|
|
104
|
+
bat: "DOS Batch", cmd: "DOS Batch", dos: "DOS Batch",
|
|
105
|
+
c: "C", cpp: "C++", cs: "C#", csharp: "C#", objectivec: "Objective-C",
|
|
106
|
+
css: "CSS", scss: "SCSS", less: "Less",
|
|
107
|
+
dart: "Dart", diff: "Diff", patch: "Diff", dns: "DNS Zone",
|
|
108
|
+
dockerfile: "Dockerfile", docker: "Dockerfile",
|
|
109
|
+
fsharp: "F#", go: "Go", golang: "Go", graphql: "GraphQL",
|
|
110
|
+
html: "HTML", xml: "XML", svg: "SVG", http: "HTTP",
|
|
111
|
+
ini: "INI", toml: "TOML", java: "Java",
|
|
112
|
+
js: "JavaScript", javascript: "JavaScript", json: "JSON",
|
|
113
|
+
kotlin: "Kotlin", lua: "Lua", makefile: "Makefile", md: "Markdown", markdown: "Markdown",
|
|
114
|
+
nginx: "Nginx", perl: "Perl", php: "PHP",
|
|
115
|
+
powershell: "PowerShell", ps: "PowerShell", ps1: "PowerShell", pwsh: "PowerShell",
|
|
116
|
+
python: "Python", py: "Python", r: "R", ruby: "Ruby", rb: "Ruby", rust: "Rust",
|
|
117
|
+
scala: "Scala", sql: "SQL", pgsql: "PostgreSQL", postgresql: "PostgreSQL",
|
|
118
|
+
swift: "Swift", ts: "TypeScript", typescript: "TypeScript",
|
|
119
|
+
vbnet: "VB.NET", vbscript: "VBScript", yaml: "YAML", yml: "YAML",
|
|
120
|
+
plaintext: "Plain Text", text: "Text"
|
|
121
|
+
};
|
|
122
|
+
|
|
96
123
|
function highlightJsBadge(opt) {
|
|
97
124
|
var options = {
|
|
98
125
|
// the selector for the badge template
|
|
@@ -198,10 +225,24 @@ function highlightJsBadge(opt) {
|
|
|
198
225
|
lang = "typescript";
|
|
199
226
|
else if (lang == "fox")
|
|
200
227
|
lang = "foxpro";
|
|
201
|
-
else if (lang == "txt")
|
|
228
|
+
else if (lang == "txt")
|
|
202
229
|
lang = "text"
|
|
203
230
|
|
|
204
|
-
|
|
231
|
+
//-- LOCAL FIX: show a full display name rather than whatever alias the author wrote
|
|
232
|
+
//-- in the fence - "Markdown" not "md", "C#" not "cs", "Bash" not "sh". A
|
|
233
|
+
//-- highlight.js 11 grammar carries its own cased `name` and is authoritative, so
|
|
234
|
+
//-- this keeps working if the pack is ever upgraded; the v9 pack vendored here has
|
|
235
|
+
//-- no such property, so the table above supplies it. Unknown languages fall through
|
|
236
|
+
//-- to the overrides above unchanged.
|
|
237
|
+
var langDef = (window.hljs && typeof window.hljs.getLanguage === "function")
|
|
238
|
+
? window.hljs.getLanguage(lang)
|
|
239
|
+
: null;
|
|
240
|
+
|
|
241
|
+
if (langDef && langDef.name)
|
|
242
|
+
lang = langDef.name;
|
|
243
|
+
else if (HDOC_LANG_DISPLAY_NAMES[lang])
|
|
244
|
+
lang = HDOC_LANG_DISPLAY_NAMES[lang];
|
|
245
|
+
|
|
205
246
|
var html = hudText.replace("{{language}}", lang)
|
|
206
247
|
.replace("{{copyIconClass}}",options.copyIconClass)
|
|
207
248
|
.trim();
|
|
@@ -305,28 +346,22 @@ function highlightJsBadge(opt) {
|
|
|
305
346
|
" .code-badge-pre {",
|
|
306
347
|
" position: relative;",
|
|
307
348
|
" }",
|
|
349
|
+
" /* Rendered as a full-width header bar above the code, not",
|
|
350
|
+
" absolutely positioned over it - overlapping the first line",
|
|
351
|
+
" made both the badge and the code unreadable. */",
|
|
308
352
|
" .code-badge {",
|
|
309
353
|
" display: flex;",
|
|
310
354
|
" flex-direction: row;",
|
|
355
|
+
" align-items: center;",
|
|
356
|
+
" justify-content: space-between;",
|
|
311
357
|
" white-space: normal;",
|
|
312
|
-
" background: transparent;",
|
|
313
358
|
" background: #333;",
|
|
314
359
|
" color: white;",
|
|
315
360
|
" font-size: 0.875em;",
|
|
316
|
-
"
|
|
317
|
-
" transition: opacity linear 0.5s;",
|
|
318
|
-
" border-radius: 0 0 0 7px;",
|
|
361
|
+
" border-radius: 7px 7px 0 0;",
|
|
319
362
|
" padding: 5px 8px 5px 8px;",
|
|
320
|
-
"
|
|
321
|
-
"
|
|
322
|
-
" top: 0;",
|
|
323
|
-
" }",
|
|
324
|
-
" .code-badge.active {",
|
|
325
|
-
" opacity: 0.8;",
|
|
326
|
-
" }",
|
|
327
|
-
"",
|
|
328
|
-
" .code-badge:hover {",
|
|
329
|
-
" opacity: .95;",
|
|
363
|
+
" width: 100%;",
|
|
364
|
+
" box-sizing: border-box;",
|
|
330
365
|
" }",
|
|
331
366
|
"",
|
|
332
367
|
" .code-badge a,",
|
|
@@ -396,23 +431,16 @@ if (highlightJsBadgeAutoLoad)
|
|
|
396
431
|
.code-badge {
|
|
397
432
|
display: flex;
|
|
398
433
|
flex-direction: row;
|
|
434
|
+
align-items: center;
|
|
435
|
+
justify-content: space-between;
|
|
399
436
|
white-space: normal;
|
|
400
|
-
background: transparent;
|
|
401
437
|
background: #333;
|
|
402
438
|
color: white;
|
|
403
439
|
font-size: 0.875em;
|
|
404
|
-
|
|
405
|
-
border-radius: 0 0 0 7px;
|
|
440
|
+
border-radius: 7px 7px 0 0;
|
|
406
441
|
padding: 5px 8px 5px 8px;
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
top: 0;
|
|
410
|
-
}
|
|
411
|
-
.code-badge.active {
|
|
412
|
-
opacity: 0.8;
|
|
413
|
-
}
|
|
414
|
-
.code-badge:hover {
|
|
415
|
-
opacity: .95;
|
|
442
|
+
width: 100%;
|
|
443
|
+
box-sizing: border-box;
|
|
416
444
|
}
|
|
417
445
|
.code-badge a,
|
|
418
446
|
.code-badge a:hover {
|