Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Large content widgets do not render properly #1781

Closed
bolinfest opened this issue Jan 25, 2020 · 2 comments
Closed

Large content widgets do not render properly #1781

bolinfest opened this issue Jan 25, 2020 · 2 comments
Assignees
Labels
editor-core info-needed Issue requires more information from poster

Comments

@bolinfest
Copy link
Contributor

As recommended on StackOverflow, I am displaying an IContentWidget over an IViewZone so that I can handle input events in my overlay. It seems that if the content widget is larger than the viewport, it does not render correctly. Note this is not an issue if I use the same domNode for the IViewZone, but then I lose the ability to receive input events.

The code sample below creates an editor with 2000 lines and inserts an IViewZone/IContentWidget combination that is 100 lines long, which should be larger than the viewport unless you have a very tall browser window...

As you can see, when the top of the widget is in view, everything is fine, but if you try to scroll to the middle, it seemingly disappears.

monaco-editor version: 0.19.3
Browser: Google Chrome
OS: macOS
Playground code that reproduces the issue:

// Code sample for Monaco Playground that demonstrates
// that when a large content widget is scrolled, it disappears.

const lines = [];
for (let i = 0; i < 2000; i++) {
    lines.push(`console.log(${i});\n`);
}

const editor = monaco.editor.create(document.getElementById("container"), {
	value: lines.join(''),
	language: "javascript"
});

const lineNumber = 7;

editor.changeViewZones(accessor => {
    const domNode = document.createElement('div');
    const zone = {
        afterLineNumber: lineNumber,
        heightInLines: 100,
        domNode,
        onComputedHeight: height => addContentWidgetWithHeight(height),
    };
    accessor.addZone(zone);
});

function addContentWidgetWithHeight(height) {
    let domNode = null;
    const contentWidget = {
        getId: function() {
            return 'my.content.widget';
        },
        getDomNode: function() {
            if (!domNode) {
                domNode = document.createElement('div');
                domNode.innerHTML = 'My content widget';
                domNode.style.background = 'grey';
                const width = editor.getDomNode().clientWidth;
                domNode.style.width = `${width}px`;
                domNode.style.height = `${height}px`;
            }
            return domNode;
        },
        getPosition: function() {
            return {
                position: {
                    lineNumber,
                    column: 1
                },
                preference: [monaco.editor.ContentWidgetPositionPreference.BELOW]
            };
        }
    };
    editor.addContentWidget(contentWidget);
}
@rebornix rebornix added bug Issue identified by VS Code Team member as probable bug editor-core labels Jan 27, 2020
@rebornix rebornix self-assigned this Jan 27, 2020
@alexdima
Copy link
Member

alexdima commented Jan 28, 2020

In this case, IMHO it would be better to pair a view zone with an overlay widget. That is what we do for the embedded experience of find all references and for the error navigation at F8.

Here is a snippet showing how this works:

const lines = [];
for (let i = 0; i < 2000; i++) {
    lines.push(`console.log(${i});\n`);
}

const editor = monaco.editor.create(document.getElementById("container"), {
	value: lines.join(''),
	language: "javascript"
});

const lineNumber = 7;

let overlayDomNode = document.createElement('div');
overlayDomNode.innerHTML = 'My overlay widget';
overlayDomNode.style.background = 'grey';

let viewZoneTop = 0;
let viewZoneHeight = 0;

editor.addOverlayWidget({
    getId: function() { return 'my.overlay.widget'; },
    getDomNode: function() { return overlayDomNode; },
    getPosition: function() { return null; }
});

editor.changeViewZones(accessor => {
    const domNode = document.createElement('div');
    const zone = {
        afterLineNumber: lineNumber,
        heightInLines: 100,
        domNode,
        onDomNodeTop: (top) => { viewZoneTop = top; layoutOverlayWidget(); },
        onComputedHeight: (height) => { viewZoneHeight = height; layoutOverlayWidget(); },
    };
    accessor.addZone(zone);
});

function layoutOverlayWidget() {
    const layoutInfo = editor.getLayoutInfo();
    overlayDomNode.style.width = `${layoutInfo.width}px`;
    overlayDomNode.style.top = `${viewZoneTop}px`;
    overlayDomNode.style.height = `${viewZoneHeight}px`;
}

Does that work for you?

@alexdima alexdima added info-needed Issue requires more information from poster and removed bug Issue identified by VS Code Team member as probable bug labels Jan 28, 2020
@vscodebot vscodebot bot closed this as completed Feb 4, 2020
@vscodebot
Copy link

vscodebot bot commented Feb 4, 2020

This issue has been closed automatically because it needs more information and has not had recent activity. See also our issue reporting guidelines.

Happy Coding!

@vscodebot vscodebot bot locked and limited conversation to collaborators Mar 20, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
editor-core info-needed Issue requires more information from poster
Projects
None yet
Development

No branches or pull requests

3 participants