diff --git a/master/buildbot/newsfragments/logviewer.bugfix b/master/buildbot/newsfragments/logviewer.bugfix new file mode 100644 index 00000000000..6e86ca29fb1 --- /dev/null +++ b/master/buildbot/newsfragments/logviewer.bugfix @@ -0,0 +1 @@ +Fixed log viewer selection and copy-paste for Firefox (:bug:`3662`). diff --git a/www/base/src/app/builders/log/logviewer/logpreview.tpl.jade b/www/base/src/app/builders/log/logviewer/logpreview.tpl.jade index abcdd771e26..2115f084524 100644 --- a/www/base/src/app/builders/log/logviewer/logpreview.tpl.jade +++ b/www/base/src/app/builders/log/logviewer/logpreview.tpl.jade @@ -11,8 +11,7 @@ div.logpreview.panel(ng-class="logpreview.log.name=='err.html' && 'panel-danger' a.btn.btn-default.btn-xs(ng-href="api/v2/logs/{{logpreview.log.logid}}/raw", description="download log") i.fa.fa-download | #{' '} download - pre.log(ng-show="logpreview.log.type!='h'") + pre.select-content.log(ng-show="logpreview.log.type!='h'") div(ng-repeat="line in logpreview.log.lines", style="height:18px") - span.linenumber.no-select {{line.number}} - span.select.no-wrap(class="{{line.class}}", ng-bind-html="line.content") + span.no-wrap(data-linenumber-content="{{line.number}}", class="{{line.class}}", ng-bind-html="line.content") div.panel-body(ng-if="logpreview.log.type=='h'", ng-bind-html="logpreview.log.content") diff --git a/www/base/src/app/builders/log/logviewer/logviewer.tpl.jade b/www/base/src/app/builders/log/logviewer/logviewer.tpl.jade index b0aa6b0a4a2..0f868102610 100644 --- a/www/base/src/app/builders/log/logviewer/logviewer.tpl.jade +++ b/www/base/src/app/builders/log/logviewer/logviewer.tpl.jade @@ -8,8 +8,7 @@ pre.row.log(ng-show="log.type!='h'", scroll-viewport) span(ng-if="log.type=='s' || log.type=='t'") div(scroll="line in lines", scroll-position="log.num_lines", load-all="loadAll", is-loading="isLoading", total-size="log.num_lines", style="height:18px") - span.linenumber.no-select {{::$index}} - span.no-wrap(class="{{::line.class}}") {{::line.content}} + span.no-wrap(data-linenumber-content="{{::$index}}", class="{{::line.class}}") {{::line.content}} div.panel(ng-if="log.type=='h'", ng-class="log.name=='err.html' && 'panel-danger' || 'panel-default'") div.panel-heading h4.panel-title {{log.name}} diff --git a/www/base/src/styles/styles.less b/www/base/src/styles/styles.less index 02c7c59a6c9..422f0ce22b9 100644 --- a/www/base/src/styles/styles.less +++ b/www/base/src/styles/styles.less @@ -82,14 +82,25 @@ -moz-user-select: none; -ms-user-select: none; user-select: none; + display: inline; } -.select { - -webkit-touch-callout: initial; - -webkit-user-select: initial; - -khtml-user-select: initial; - -moz-user-select: initial; - -ms-user-select: initial; - user-select: initial; +.select-content { + -webkit-touch-callout: text; + -webkit-user-select: text; + -khtml-user-select: text; + -moz-user-select: text; + -ms-user-select: text; + user-select: text; +} +/* https://danoc.me/blog/css-prevent-copy/ +Firefox will insert newlines if the selection go over a no-select span, so we need to implement them with ::before +*/ +[data-linenumber-content]::before, +[data-linenumber-content--before]::before, +[data-linenumber-content--after]::after { + content: attr(data-linenumber-content); + color: #c7c7c7; + padding-right: 10px; } .avatar {