From 75e5ff36f363f6a84a3dce209446774ff2d13076 Mon Sep 17 00:00:00 2001 From: Kevin Burke Date: Fri, 21 Apr 2017 19:13:36 -0700 Subject: [PATCH] godoc: make line numbers unselectable Insert line numbers via a ::before pseudo-element so you can't select them when you copy text. See the code comment for more information. Fixes golang/go#20077. Change-Id: I24a5b17786a52c8107b4f830e824526ba03bc38d Reviewed-on: https://go-review.googlesource.com/41418 Reviewed-by: Brad Fitzpatrick --- godoc/server.go | 11 ++++++++++- godoc/static/static.go | 5 +++++ godoc/static/style.css | 5 +++++ 3 files changed, 20 insertions(+), 1 deletion(-) diff --git a/godoc/server.go b/godoc/server.go index 162e5a6aae..ffe599725f 100644 --- a/godoc/server.go +++ b/godoc/server.go @@ -621,7 +621,16 @@ func formatGoSource(buf *bytes.Buffer, text []byte, links []analysis.Link, patte // linkWriter, so we have to add line spans as another pass. n := 1 for _, line := range bytes.Split(buf.Bytes(), []byte("\n")) { - fmt.Fprintf(saved, "%6d\t", n, n) + // The line numbers are inserted into the document via a CSS ::before + // pseudo-element. This prevents them from being copied when users + // highlight and copy text. + // ::before is supported in 98% of browsers: https://caniuse.com/#feat=css-gencontent + // This is also the trick Github uses to hide line numbers. + // + // The first tab for the code snippet needs to start in column 9, so + // it indents a full 8 spaces, hence the two nbsp's. Otherwise the tab + // character only indents about two spaces. + fmt.Fprintf(saved, `  `, n, n) n++ saved.Write(line) saved.WriteByte('\n') diff --git a/godoc/static/static.go b/godoc/static/static.go index c89ffaadfe..c89157653b 100644 --- a/godoc/static/static.go +++ b/godoc/static/static.go @@ -2932,6 +2932,11 @@ pre .ln { -ms-user-select: none; user-select: none; } +.ln::before { + /* Inserting the line numbers as a ::before pseudo-element avoids making + * them selectable; it's the trick Github uses as well. */ + content: attr(data-content); +} body { color: #222; } diff --git a/godoc/static/style.css b/godoc/static/style.css index 025327b8f1..e89ac29049 100644 --- a/godoc/static/style.css +++ b/godoc/static/style.css @@ -37,6 +37,11 @@ pre .ln { -ms-user-select: none; user-select: none; } +.ln::before { + /* Inserting the line numbers as a ::before pseudo-element avoids making + * them selectable; it's the trick Github uses as well. */ + content: attr(data-content); +} body { color: #222; }