Skip to content

Commit 94e637f

Browse files
committed
fix: harden FocusableBrowserInformationControl.updateBrowserSize
1 parent b6d0459 commit 94e637f

File tree

1 file changed

+47
-23
lines changed

1 file changed

+47
-23
lines changed

org.eclipse.lsp4e/src/org/eclipse/lsp4e/operations/hover/FocusableBrowserInformationControl.java

Lines changed: 47 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -94,57 +94,79 @@ protected void createContent(Composite parent) {
9494
}
9595

9696
private void updateBrowserSize(final Browser browser) {
97+
updateBrowserSize(browser, 1);
98+
}
99+
100+
private void updateBrowserSize(final Browser browser, final int attempt) {
101+
if (attempt > 100) // ~1s total
102+
return;
103+
97104
if (getShell().isDisposed() || browser.isDisposed() || getInput() == null)
98105
return;
99106

100-
@Nullable
101-
Point constraints = getSizeConstraints();
102-
Point hint = computeSizeHint();
107+
final @Nullable Point constraints = getSizeConstraints();
108+
final Point hint = computeSizeHint();
103109
setSize(hint.x, hint.y);
104110

105-
if (!"complete".equals(safeEvaluate(browser, "return document.readyState"))) { //$NON-NLS-1$ //$NON-NLS-2$
106-
UI.getDisplay().timerExec(50, () -> updateBrowserSize(browser));
111+
final var docReadyState = safeEvaluate(browser, "return document.readyState"); //$NON-NLS-1$
112+
if (!"complete".equals(docReadyState)) { //$NON-NLS-1$
113+
retryUpdateBrowserSize(browser, attempt);
114+
return;
115+
}
116+
117+
safeExecute(browser, "document.getElementsByTagName('html')[0].style.whiteSpace = 'nowrap'"); //$NON-NLS-1$
118+
final Object widthObj = safeEvaluate(browser, "var b = document.body; return b && b.scrollWidth"); //$NON-NLS-1$
119+
if (!(widthObj instanceof final Number widthValue)) {
120+
retryUpdateBrowserSize(browser, attempt);
121+
return;
122+
}
123+
double width = 20 + widthValue.doubleValue();
124+
setSize((int) width, hint.y);
125+
126+
safeExecute(browser, "document.getElementsByTagName('html')[0].style.whiteSpace = 'normal'"); //$NON-NLS-1$
127+
final Object heightObj = safeEvaluate(browser, "var b = document.body; return b && b.scrollHeight"); //$NON-NLS-1$
128+
if (!(heightObj instanceof final Number heightValue)) {
129+
retryUpdateBrowserSize(browser, attempt);
107130
return;
108131
}
109132

110-
safeExecute(browser, "document.getElementsByTagName(\"html\")[0].style.whiteSpace = \"nowrap\""); //$NON-NLS-1$
111-
Double width = 20
112-
+ (safeEvaluate(browser, "return document.body.scrollWidth;") instanceof Double evaluated ? evaluated //$NON-NLS-1$
113-
: 0);
114-
setSize(width.intValue(), hint.y);
115-
116-
safeExecute(browser, "document.getElementsByTagName(\"html\")[0].style.whiteSpace = \"normal\""); //$NON-NLS-1$
117-
Double height = safeEvaluate(browser, "return document.body.scrollHeight;") instanceof Double evaluated //$NON-NLS-1$
118-
? evaluated
119-
: 0d;
120-
Object marginTop = safeEvaluate(browser, "return window.getComputedStyle(document.body).marginTop;"); //$NON-NLS-1$
121-
Object marginBottom = safeEvaluate(browser, "return window.getComputedStyle(document.body).marginBottom;"); //$NON-NLS-1$
133+
double height = heightValue.doubleValue();
122134
if (Platform.getPreferencesService().getBoolean(EditorsUI.PLUGIN_ID,
123135
AbstractDecoratedTextEditorPreferenceConstants.EDITOR_SHOW_TEXT_HOVER_AFFORDANCE, true, null)) {
124-
FontData[] fontDatas = JFaceResources.getDialogFont().getFontData();
136+
final FontData[] fontDatas = JFaceResources.getDialogFont().getFontData();
125137
height += fontDatas[0].getHeight();
126138
}
127139

128140
width = width * 1.5;
129141
if (Util.isWin32()) {
142+
Object marginTop = safeEvaluate(browser,
143+
"var b = document.body; return b && window.getComputedStyle(b).marginTop"); //$NON-NLS-1$
144+
Object marginBottom = safeEvaluate(browser,
145+
"var b = document.body; return b && window.getComputedStyle(b).marginBottom"); //$NON-NLS-1$
130146
height = adjust(height, marginTop);
131147
height = adjust(height, marginBottom);
132148
}
133149
if (constraints != null && constraints.x < width) {
134-
width = (double) constraints.x;
150+
width = constraints.x;
135151
}
136152
if (constraints != null && constraints.y < height) {
137-
height = (double) constraints.y;
153+
height = constraints.y;
138154
}
139155

140-
setSize(width.intValue(), height.intValue());
156+
setSize((int) width, (int) height);
157+
}
158+
159+
private void retryUpdateBrowserSize(final Browser browser, final int currentAttempt) {
160+
UI.getDisplay().timerExec(10, () -> updateBrowserSize(browser, currentAttempt + 1));
141161
}
142162

143163
private static @Nullable Object safeEvaluate(Browser browser, String expression) {
144164
try {
145165
return browser.evaluate(expression);
146166
} catch (Exception ex) {
147-
LanguageServerPlugin.logError(ex);
167+
if (LanguageServerPlugin.DEBUG || LanguageServerPlugin.isLogTraceEnabled()) {
168+
LanguageServerPlugin.logError("Failed to evaluate browser expression: " + expression, ex); //$NON-NLS-1$
169+
}
148170
}
149171
return null;
150172
}
@@ -153,7 +175,9 @@ private static boolean safeExecute(Browser browser, String expression) {
153175
try {
154176
return browser.execute(expression);
155177
} catch (Exception ex) {
156-
LanguageServerPlugin.logError(ex);
178+
if (LanguageServerPlugin.DEBUG || LanguageServerPlugin.isLogTraceEnabled()) {
179+
LanguageServerPlugin.logError("Failed to execute browser expression: " + expression, ex); //$NON-NLS-1$
180+
}
157181
}
158182
return false;
159183
}

0 commit comments

Comments
 (0)