Support maximizing editor to viewport size

Related feedback:
https://github.com/uBlockOrigin/uBlock-issues/issues/3161#issuecomment-1991066618
This commit is contained in:
Raymond Hill 2024-03-12 11:25:50 -04:00
parent 710d8c6494
commit 664dd95700
No known key found for this signature in database
GPG Key ID: 25E1490B761470C2
4 changed files with 77 additions and 31 deletions

View File

@ -3,6 +3,13 @@
overflow: hidden; overflow: hidden;
position: relative; position: relative;
} }
.codeMirrorContainer.cm-maximized {
bottom: 0;
left: 0;
position: absolute;
right: 0;
top: 0;
}
.CodeMirror { .CodeMirror {
background-color: var(--surface-0); background-color: var(--surface-0);
box-sizing: border-box; box-sizing: border-box;
@ -176,16 +183,42 @@
text-align: end; text-align: end;
} }
.cm-search-widget .cm-maximize {
fill: none;
flex-grow: 0;
font-size: 140%;
height: 1em;
stroke-width: 3px;
stroke: var(--ink-0);
width: 1em;
}
.cm-search-widget .cm-maximize * {
pointer-events: none;
}
.codeMirrorContainer[data-maximizable="false"] .cm-search-widget .cm-maximize {
display: none;
}
.codeMirrorContainer .cm-search-widget .cm-maximize svg > path:nth-child(2),
.codeMirrorContainer.cm-maximized .cm-search-widget .cm-maximize svg > path:nth-child(1) {
display: none;
}
.codeMirrorContainer.cm-maximized .cm-search-widget .cm-maximize svg > path:nth-child(2) {
display: initial;
}
html:not(.mobile) .cm-search-widget .cm-maximize:hover {
transform: scale(1.2);
}
.cm-search-widget-input { .cm-search-widget-input {
display: inline-flex; display: inline-flex;
flex-grow: 1; flex-grow: 1;
flex-wrap: nowrap;
} }
.cm-search-widget .fa-icon { .cm-search-widget .fa-icon {
fill: var(--cm-gutter-ink);
font-size: 140%; font-size: 140%;
} }
.cm-search-widget .fa-icon:not(.fa-icon-ro):hover { html:not(.mobile) .cm-search-widget .fa-icon:not(.fa-icon-ro):hover {
fill: var(--ink-1); transform: scale(1.2);
} }
.cm-search-widget-input input { .cm-search-widget-input input {
border: 1px solid var(--cm-gutter-ink); border: 1px solid var(--cm-gutter-ink);
@ -198,7 +231,6 @@
display: inline-flex; display: inline-flex;
flex-grow: 0; flex-grow: 0;
font-size: var(--font-size-smaller); font-size: var(--font-size-smaller);
min-width: 6em;
visibility: hidden; visibility: hidden;
} }
.cm-search-widget[data-query] .cm-search-widget-count { .cm-search-widget[data-query] .cm-search-widget-count {
@ -207,9 +239,6 @@
.cm-search-widget[data-query] .cm-search-widget-count:empty { .cm-search-widget[data-query] .cm-search-widget-count:empty {
visibility: hidden; visibility: hidden;
} }
.cm-search-widget .cm-search-widget-button:hover {
color: #000;
}
.cm-search-widget .sourceURL[href=""] { .cm-search-widget .sourceURL[href=""] {
visibility: hidden; visibility: hidden;
} }

View File

@ -52,11 +52,11 @@ body {
margin: 0; margin: 0;
padding: 0; padding: 0;
} }
a { a:not(.fa-icon) {
color: var(--link-ink); color: var(--link-ink);
fill: var(--link-ink); fill: var(--link-ink);
} }
a:hover { a:not(.fa-icon):hover {
color: var(--link-hover-ink); color: var(--link-hover-ink);
fill: var(--link-hover-ink); fill: var(--link-hover-ink);
} }

View File

@ -60,6 +60,7 @@ import './codemirror/ubo-static-filtering.js';
lineWrapping: true, lineWrapping: true,
matchBrackets: true, matchBrackets: true,
maxScanLines: 1, maxScanLines: 1,
maximizable: false,
readOnly: true, readOnly: true,
styleActiveLine: { styleActiveLine: {
nonEmpty: true, nonEmpty: true,

View File

@ -33,6 +33,15 @@ import { i18n$ } from '../i18n.js';
{ {
const CodeMirror = self.CodeMirror; const CodeMirror = self.CodeMirror;
CodeMirror.defineOption('maximizable', true, (cm, maximizable) => {
if ( typeof maximizable !== 'boolean' ) { return; }
const wrapper = cm.getWrapperElement();
if ( wrapper === null ) { return; }
const container = wrapper.closest('.codeMirrorContainer');
if ( container === null ) { return; }
container.dataset.maximizable = `${maximizable}`;
});
const searchOverlay = function(query, caseInsensitive) { const searchOverlay = function(query, caseInsensitive) {
if ( typeof query === 'string' ) if ( typeof query === 'string' )
query = new RegExp( query = new RegExp(
@ -90,7 +99,8 @@ import { i18n$ } from '../i18n.js';
}; };
const searchWidgetClickHandler = function(cm, ev) { const searchWidgetClickHandler = function(cm, ev) {
const tcl = ev.target.classList; const target = ev.target;
const tcl = target.classList;
if ( tcl.contains('cm-search-widget-up') ) { if ( tcl.contains('cm-search-widget-up') ) {
findNext(cm, -1); findNext(cm, -1);
} else if ( tcl.contains('cm-search-widget-down') ) { } else if ( tcl.contains('cm-search-widget-down') ) {
@ -99,8 +109,13 @@ import { i18n$ } from '../i18n.js';
findNextError(cm, -1); findNextError(cm, -1);
} else if ( tcl.contains('cm-linter-widget-down') ) { } else if ( tcl.contains('cm-linter-widget-down') ) {
findNextError(cm, 1); findNextError(cm, 1);
} else if ( tcl.contains('cm-maximize') ) {
const container = target.closest('.codeMirrorContainer');
if ( container !== null ) {
container.classList.toggle('cm-maximized');
} }
if ( ev.target.localName !== 'input' ) { }
if ( target.localName !== 'input' ) {
ev.preventDefault(); ev.preventDefault();
} else { } else {
ev.stopImmediatePropagation(); ev.stopImmediatePropagation();
@ -458,26 +473,27 @@ import { i18n$ } from '../i18n.js';
}; };
{ {
const searchWidgetTemplate = const searchWidgetTemplate = [
'<div class="cm-search-widget-template" style="display:none;">' + '<div class="cm-search-widget-template" style="display:none;">',
'<div class="cm-search-widget">' + '<div class="cm-search-widget">',
'<span class="cm-search-widget-input">' + '<span class="cm-maximize"><svg viewBox="0 0 40 40"><path d="M4,16V4h12M24,4H36V16M4,24V36H16M36,24V36H24" /><path d="M14 2.5v12h-12M38 14h-12v-12M14 38v-12h-12M26 38v-12h12" /></svg></span>&ensp;',
'<span class="fa-icon fa-icon-ro">search</span>&ensp;' + '<span class="cm-search-widget-input">',
'<input type="search" spellcheck="false">&emsp;' + '<input type="search" spellcheck="false" placeholder="&#x26B2;">&ensp;',
'<span class="cm-search-widget-up cm-search-widget-button fa-icon">angle-up</span>&nbsp;' + '<span class="cm-search-widget-up cm-search-widget-button fa-icon">angle-up</span>&nbsp;',
'<span class="cm-search-widget-down cm-search-widget-button fa-icon fa-icon-vflipped">angle-up</span>&emsp;' + '<span class="cm-search-widget-down cm-search-widget-button fa-icon fa-icon-vflipped">angle-up</span>&ensp;',
'<span class="cm-search-widget-count"></span>' + '<span class="cm-search-widget-count"></span>',
'</span>' + '</span>',
'<span class="cm-linter-widget" data-lint="0">' + '<span class="cm-linter-widget" data-lint="0">',
'<span class="cm-linter-widget-count"></span>&emsp;' + '<span class="cm-linter-widget-count"></span>&ensp;',
'<span class="cm-linter-widget-up cm-search-widget-button fa-icon">angle-up</span>&nbsp;' + '<span class="cm-linter-widget-up cm-search-widget-button fa-icon">angle-up</span>&nbsp;',
'<span class="cm-linter-widget-down cm-search-widget-button fa-icon fa-icon-vflipped">angle-up</span>&emsp;' + '<span class="cm-linter-widget-down cm-search-widget-button fa-icon fa-icon-vflipped">angle-up</span>&ensp;',
'</span>' + '</span>',
'<span>' + '<span>',
'<a class="fa-icon sourceURL" href>external-link</a>' + '<a class="fa-icon sourceURL" href>external-link</a>',
'</span>' + '</span>',
'</div>' + '</div>',
'</div>'; '</div>',
].join('\n');
const domParser = new DOMParser(); const domParser = new DOMParser();
const doc = domParser.parseFromString(searchWidgetTemplate, 'text/html'); const doc = domParser.parseFromString(searchWidgetTemplate, 'text/html');
const widgetTemplate = document.adoptNode(doc.body.firstElementChild); const widgetTemplate = document.adoptNode(doc.body.firstElementChild);