Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion src/editor/Editor.js
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,8 @@ define(function (require, exports, module) {
EditorPreferences = require("./EditorHelper/EditorPreferences"),
ChangeHelper = require("./EditorHelper/ChangeHelper"),
ErrorPopupHelper = require("./EditorHelper/ErrorPopupHelper"),
InlineWidgetHelper = require("./EditorHelper/InlineWidgetHelper");
InlineWidgetHelper = require("./EditorHelper/InlineWidgetHelper"),
ScrollbarHelper = require("./EditorHelper/ScrollbarHelper");

/* Editor preferences */

Expand Down Expand Up @@ -408,6 +409,9 @@ define(function (require, exports, module) {
// Fail silently; drag image override is non-critical.
}

// Click-to-jump on the native scrollbars (instead of slow viewport-at-a-time paging).
ScrollbarHelper.installClickToJump(self);

// Can't get CodeMirror's focused state without searching for
// CodeMirror-focused. Instead, track focus via onFocus and onBlur
// options and track state with this._focused
Expand Down
91 changes: 91 additions & 0 deletions src/editor/EditorHelper/ScrollbarHelper.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
/*
* GNU AGPL-3.0 License
*
* Copyright (c) 2021 - present core.ai . All rights reserved.
* Original work Copyright (c) 2012 - 2021 Adobe Systems Incorporated. All rights reserved.
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License
* for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see https://opensource.org/licenses/AGPL-3.0.
*
*/

/**
* Editor scrollbar behaviour helpers. Only to be used from Editor.js.
*/

define(function (require, exports, module) {

/**
* Install click-to-jump on an editor's native scrollbars: clicking an empty part of the track
* jumps straight to that proportional position, instead of the browser default of paging one
* viewport at a time (painfully slow to reach a far-off spot in a large file). A click on the
* thumb is left to the native drag.
*
* CodeMirror's "native" scrollbars are real overflow:scroll <div>s (.CodeMirror-vscrollbar /
* .CodeMirror-hscrollbar); setting their scroll offset syncs the editor, since CodeMirror listens
* to their scroll event. Unlike most native scrollbars, this webview still delivers mousedown on
* them, so we can intercept a track click.
*
* @param {!Editor} editor
*/
function installClickToJump(editor) {

Check warning on line 41 in src/editor/EditorHelper/ScrollbarHelper.js

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Move function 'installClickToJump' to the outer scope.

See more on https://sonarcloud.io/project/issues?id=phcode-dev_phoenix&issues=AZ8ELF54GUTM2XMIwQU-&open=AZ8ELF54GUTM2XMIwQU-&pullRequest=2991
const cm = editor._codeMirror;
const wrapper = cm && cm.getWrapperElement();

Check warning on line 43 in src/editor/EditorHelper/ScrollbarHelper.js

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Prefer using an optional chain expression instead, as it's more concise and easier to read.

See more on https://sonarcloud.io/project/issues?id=phcode-dev_phoenix&issues=AZ8ELF54GUTM2XMIwQU_&open=AZ8ELF54GUTM2XMIwQU_&pullRequest=2991
if (!wrapper) {
return;
}

// Capture phase so we can suppress the native paging before it runs.
wrapper.addEventListener("mousedown", function (e) {
const el = e.target;
if (e.button !== 0 || !el || !el.classList) {

Check warning on line 51 in src/editor/EditorHelper/ScrollbarHelper.js

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Prefer using an optional chain expression instead, as it's more concise and easier to read.

See more on https://sonarcloud.io/project/issues?id=phcode-dev_phoenix&issues=AZ8ELF54GUTM2XMIwQVA&open=AZ8ELF54GUTM2XMIwQVA&pullRequest=2991
return;
}
let axis;
if (el.classList.contains("CodeMirror-vscrollbar")) {
axis = "v";
} else if (el.classList.contains("CodeMirror-hscrollbar")) {
axis = "h";
} else {
return;
}

const rect = el.getBoundingClientRect();
const view = (axis === "v") ? el.clientHeight : el.clientWidth; // visible track px
const full = (axis === "v") ? el.scrollHeight : el.scrollWidth; // scrollable px
if (full <= view) {
return; // nothing to scroll
}
const cur = (axis === "v") ? el.scrollTop : el.scrollLeft;
const thumbStart = (cur / full) * view;
const thumbSize = (view / full) * view;
const clickPos = (axis === "v") ? (e.clientY - rect.top) : (e.clientX - rect.left);
if (clickPos >= thumbStart && clickPos <= thumbStart + thumbSize) {
return; // on the thumb - let the native drag handle it
}

// Track click: centre the thumb on the cursor and jump there immediately.
let target = (clickPos / view) * full - view / 2;
target = Math.max(0, Math.min(target, full - view));
e.preventDefault();
if (axis === "v") {
el.scrollTop = target;
} else {
el.scrollLeft = target;
}
}, true);
// No explicit removal: the wrapper element is removed on editor.destroy().
}

exports.installClickToJump = installClickToJump;
});
12 changes: 10 additions & 2 deletions src/features/ParameterHintsManager.js
Original file line number Diff line number Diff line change
Expand Up @@ -269,8 +269,16 @@ define(function (require, exports, module) {
}

if (hints.parameters.length > 0) {
let token = editor.getToken(hints.functionCallPos);
_formatParameterHint(token.string, hints.parameters, appendSeparators, appendParameter);
// Prefer a function name supplied by the provider (LSP signatureHelp gives the full
// signature label). Only fall back to the editor token for providers that locate the call
// site themselves (Tern sets functionCallPos); without that fallback guard, an LSP hint -
// whose functionCallPos is undefined - would read the token at the caret, i.e. the just
// typed "(", and render an unbalanced "((".
let functionName = hints.functionName;
if (functionName == null) {
functionName = editor.getToken(hints.functionCallPos).string;
}
_formatParameterHint(functionName, hints.parameters, appendSeparators, appendParameter);
} else {
$hintContent.append(_.escape(Strings.NO_ARGUMENTS));
}
Expand Down
Loading
Loading