Skip to content

Commit 4368c1a

Browse files
committed
work
1 parent c509848 commit 4368c1a

21 files changed

Lines changed: 948 additions & 126 deletions

File tree

dist/build/browserslist_index/browserslist_index.js

Lines changed: 60 additions & 31 deletions
Large diffs are not rendered by default.

dist/build/build.js

Lines changed: 44 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4119,7 +4119,9 @@ const jsenvPluginDirectoryReferenceEffect = (
41194119
} else if (reference.specifierPathname.endsWith("./")) ; else {
41204120
const directoryRelativeUrl = urlToRelativeUrl(
41214121
reference.url,
4122-
reference.ownerUrlInfo.originalUrl,
4122+
// the root url info has no originalUrl; it owns the reference
4123+
// created for an incoming request ("http_request")
4124+
reference.ownerUrlInfo.originalUrl || reference.ownerUrlInfo.url,
41234125
);
41244126
reference.filenameHint = directoryRelativeUrl;
41254127
}
@@ -7242,6 +7244,9 @@ const jsenvPluginFsRedirection = ({
72427244
const { search, hash } = urlObject;
72437245
urlObject.search = "";
72447246
urlObject.hash = "";
7247+
// must be read before applyFsStatEffectsOnUrlObject which forces the
7248+
// trailing slash on directories
7249+
const specifierUsesTrailingSlash = urlObject.pathname.endsWith("/");
72457250
applyFsStatEffectsOnUrlObject(urlObject, fsStat);
72467251
const shouldApplyFilesystemMagicResolution =
72477252
reference.type === "js_import";
@@ -7271,20 +7276,16 @@ const jsenvPluginFsRedirection = ({
72717276
// url has an extension, we assume it's a file request -> let 404 happen
72727277
return null;
72737278
}
7274-
const { requestedUrl, rootDirectoryUrl, mainFilePath } =
7275-
reference.ownerUrlInfo.context;
7276-
if (!requestedUrl) {
7277-
// the SPA fallback answers a request; during build there is none
7279+
if (specifierUsesTrailingSlash) {
7280+
// the trailing slash asks for a directory and there is none here
7281+
// -> let 404 happen (same reasoning as the extension above)
72787282
return null;
72797283
}
7280-
const closestHtmlRootFile = getClosestHtmlRootFile(
7281-
requestedUrl,
7282-
rootDirectoryUrl,
7283-
);
7284-
if (closestHtmlRootFile) {
7285-
return closestHtmlRootFile;
7284+
const spaFallbackUrl = getSpaFallbackUrl(reference);
7285+
if (spaFallbackUrl) {
7286+
return spaFallbackUrl;
72867287
}
7287-
return new URL(mainFilePath, rootDirectoryUrl);
7288+
return null;
72887289
}
72897290
if (fsStat.isDirectory()) {
72907291
// When requesting a directory, check if we have an HTML entry file for that directory
@@ -7293,6 +7294,21 @@ const jsenvPluginFsRedirection = ({
72937294
reference.fsStat = readEntryStatSync(directoryEntryFileUrl);
72947295
return directoryEntryFileUrl;
72957296
}
7297+
if (!specifierUsesTrailingSlash) {
7298+
// the trailing slash is what tells a directory apart from a route:
7299+
// "/join/" is the directory, "/join" is a route owned by the SPA
7300+
// even when "join/" exists in the source files.
7301+
// Without this a source directory would shadow the route having
7302+
// the same name and the SPA would be unreachable in dev while
7303+
// being perfectly fine once built
7304+
const spaFallbackUrl = getSpaFallbackUrl(reference);
7305+
if (spaFallbackUrl) {
7306+
reference.fsStat = readEntryStatSync(spaFallbackUrl, {
7307+
nullIfNotFound: true,
7308+
});
7309+
return spaFallbackUrl;
7310+
}
7311+
}
72967312
}
72977313
}
72987314
if (!fsStat) {
@@ -7355,6 +7371,22 @@ const getDirectoryEntryFileUrl = (directoryUrl) => {
73557371
}
73567372
return null;
73577373
};
7374+
const getSpaFallbackUrl = (reference) => {
7375+
const { requestedUrl, rootDirectoryUrl, mainFilePath } =
7376+
reference.ownerUrlInfo.context;
7377+
if (!requestedUrl) {
7378+
// the SPA fallback answers a request; during build there is none
7379+
return null;
7380+
}
7381+
const closestHtmlRootFile = getClosestHtmlRootFile(
7382+
requestedUrl,
7383+
rootDirectoryUrl,
7384+
);
7385+
if (closestHtmlRootFile) {
7386+
return closestHtmlRootFile;
7387+
}
7388+
return String(new URL(mainFilePath, rootDirectoryUrl));
7389+
};
73587390
const getClosestHtmlRootFile = (requestedUrl, serverRootDirectoryUrl) => {
73597391
let directoryUrl = new URL("./", requestedUrl);
73607392
while (true) {

dist/start_dev_server/start_dev_server.js

Lines changed: 56 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -4075,6 +4075,9 @@ const jsenvPluginFsRedirection = ({
40754075
const { search, hash } = urlObject;
40764076
urlObject.search = "";
40774077
urlObject.hash = "";
4078+
// must be read before applyFsStatEffectsOnUrlObject which forces the
4079+
// trailing slash on directories
4080+
const specifierUsesTrailingSlash = urlObject.pathname.endsWith("/");
40784081
applyFsStatEffectsOnUrlObject(urlObject, fsStat);
40794082
const shouldApplyFilesystemMagicResolution =
40804083
reference.type === "js_import";
@@ -4104,20 +4107,16 @@ const jsenvPluginFsRedirection = ({
41044107
// url has an extension, we assume it's a file request -> let 404 happen
41054108
return null;
41064109
}
4107-
const { requestedUrl, rootDirectoryUrl, mainFilePath } =
4108-
reference.ownerUrlInfo.context;
4109-
if (!requestedUrl) {
4110-
// the SPA fallback answers a request; during build there is none
4110+
if (specifierUsesTrailingSlash) {
4111+
// the trailing slash asks for a directory and there is none here
4112+
// -> let 404 happen (same reasoning as the extension above)
41114113
return null;
41124114
}
4113-
const closestHtmlRootFile = getClosestHtmlRootFile(
4114-
requestedUrl,
4115-
rootDirectoryUrl,
4116-
);
4117-
if (closestHtmlRootFile) {
4118-
return closestHtmlRootFile;
4115+
const spaFallbackUrl = getSpaFallbackUrl(reference);
4116+
if (spaFallbackUrl) {
4117+
return spaFallbackUrl;
41194118
}
4120-
return new URL(mainFilePath, rootDirectoryUrl);
4119+
return null;
41214120
}
41224121
if (fsStat.isDirectory()) {
41234122
// When requesting a directory, check if we have an HTML entry file for that directory
@@ -4126,6 +4125,21 @@ const jsenvPluginFsRedirection = ({
41264125
reference.fsStat = readEntryStatSync(directoryEntryFileUrl);
41274126
return directoryEntryFileUrl;
41284127
}
4128+
if (!specifierUsesTrailingSlash) {
4129+
// the trailing slash is what tells a directory apart from a route:
4130+
// "/join/" is the directory, "/join" is a route owned by the SPA
4131+
// even when "join/" exists in the source files.
4132+
// Without this a source directory would shadow the route having
4133+
// the same name and the SPA would be unreachable in dev while
4134+
// being perfectly fine once built
4135+
const spaFallbackUrl = getSpaFallbackUrl(reference);
4136+
if (spaFallbackUrl) {
4137+
reference.fsStat = readEntryStatSync(spaFallbackUrl, {
4138+
nullIfNotFound: true,
4139+
});
4140+
return spaFallbackUrl;
4141+
}
4142+
}
41294143
}
41304144
}
41314145
if (!fsStat) {
@@ -4188,6 +4202,22 @@ const getDirectoryEntryFileUrl = (directoryUrl) => {
41884202
}
41894203
return null;
41904204
};
4205+
const getSpaFallbackUrl = (reference) => {
4206+
const { requestedUrl, rootDirectoryUrl, mainFilePath } =
4207+
reference.ownerUrlInfo.context;
4208+
if (!requestedUrl) {
4209+
// the SPA fallback answers a request; during build there is none
4210+
return null;
4211+
}
4212+
const closestHtmlRootFile = getClosestHtmlRootFile(
4213+
requestedUrl,
4214+
rootDirectoryUrl,
4215+
);
4216+
if (closestHtmlRootFile) {
4217+
return closestHtmlRootFile;
4218+
}
4219+
return String(new URL(mainFilePath, rootDirectoryUrl));
4220+
};
41914221
const getClosestHtmlRootFile = (requestedUrl, serverRootDirectoryUrl) => {
41924222
let directoryUrl = new URL("./", requestedUrl);
41934223
while (true) {
@@ -4995,7 +5025,9 @@ const jsenvPluginDirectoryReferenceEffect = (
49955025
} else if (reference.specifierPathname.endsWith("./")) ; else {
49965026
const directoryRelativeUrl = urlToRelativeUrl(
49975027
reference.url,
4998-
reference.ownerUrlInfo.originalUrl,
5028+
// the root url info has no originalUrl; it owns the reference
5029+
// created for an incoming request ("http_request")
5030+
reference.ownerUrlInfo.originalUrl || reference.ownerUrlInfo.url,
49995031
);
50005032
reference.filenameHint = directoryRelativeUrl;
50015033
}
@@ -11421,6 +11453,14 @@ const devServerPluginServeSourceFiles = ({
1142111453
!inlineParentUrlInfo &&
1142211454
!urlInfo.response &&
1142311455
urlInfo.content !== undefined &&
11456+
// content can be defined while a cook is still in flight (a file
11457+
// watcher invalidation re-cooking in the background, for
11458+
// instance): at that point it holds the raw fetched content,
11459+
// transformations not applied yet. Serving that would send an
11460+
// html without any of the injected scripts. Only finalized
11461+
// content is a complete response; anything else must go through
11462+
// cook() below, which joins the pending cook (see debounceCook).
11463+
urlInfo.contentFinalized &&
1142411464
!cacheIsDisabledInResponseHeader(urlInfo) &&
1142511465
// a "?hot" request exists to bypass every cache, this one
1142611466
// included: it must be cooked, because cooking is what rewrites
@@ -11465,7 +11505,10 @@ const devServerPluginServeSourceFiles = ({
1146511505
}
1146611506
response = {
1146711507
url: reference.url,
11468-
status: 200,
11508+
// a plugin can cook a complete response body for an url that is
11509+
// not a 200: the directory listing does this to answer a request
11510+
// for a file that does not exist with the explorer page
11511+
status: urlInfo.status,
1146911512
headers: {
1147011513
// when we send eTag to the client the next request to the server
1147111514
// will send etag in request headers.

packages/frontend/dom/dist/jsenv_dom.js

Lines changed: 37 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -7029,24 +7029,45 @@ const getScrollport = (scrollBox, scrollContainer) => {
70297029
};
70307030
};
70317031

7032-
// https://davidwalsh.name/detect-scrollbar-width
7032+
/**
7033+
* Returns [verticalScrollbarWidth, horizontalScrollbarHeight] as currently
7034+
* rendered by `scrollableElement`, in px. Returns zeros when the element has no
7035+
* classic scrollbar: no overflow, overlay scrollbars, `scrollbar-width: none`,
7036+
* or a `::-webkit-scrollbar { display: none }` rule.
7037+
*
7038+
* The measurement is taken on the element itself (its own border box versus its
7039+
* own content box) rather than on a probe node appended inside it. A probe
7040+
* cannot answer this question: `scrollbar-width` and `::-webkit-scrollbar` are
7041+
* not inherited, so a probe reports the platform default scrollbar size even
7042+
* when the element renders no scrollbar at all.
7043+
*/
70337044
const measureScrollbar = (scrollableElement) => {
7034-
const hasXScrollbar =
7035-
scrollableElement.scrollHeight > scrollableElement.clientHeight;
7036-
const hasYScrollbar =
7037-
scrollableElement.scrollWidth > scrollableElement.clientWidth;
7038-
if (!hasXScrollbar && !hasYScrollbar) {
7039-
return [0, 0];
7040-
}
7041-
const scrollDiv = document.createElement("div");
7042-
scrollDiv.style.cssText = `position: absolute; width: 100px; height: 100px; overflow: scroll; pointer-events: none; visibility: hidden;`;
7043-
scrollableElement.appendChild(scrollDiv);
7044-
const scrollbarWidth = scrollDiv.offsetWidth - scrollDiv.clientWidth;
7045-
const scrollbarHeight = scrollDiv.offsetHeight - scrollDiv.clientHeight;
7046-
scrollableElement.removeChild(scrollDiv);
7045+
if (
7046+
scrollableElement === document.documentElement ||
7047+
scrollableElement === document.scrollingElement
7048+
) {
7049+
// documentElement.clientWidth/Height report the viewport minus its
7050+
// scrollbars, not this element's own box (which `max-width` can shrink), so
7051+
// the border box to compare against is the window itself.
7052+
return [
7053+
snapToPixel(window.innerWidth - document.documentElement.clientWidth),
7054+
snapToPixel(window.innerHeight - document.documentElement.clientHeight),
7055+
];
7056+
}
7057+
const { left, right, top, bottom } = getBorderSizes(scrollableElement);
7058+
const scrollbarWidth =
7059+
scrollableElement.offsetWidth -
7060+
scrollableElement.clientWidth -
7061+
left -
7062+
right;
7063+
const scrollbarHeight =
7064+
scrollableElement.offsetHeight -
7065+
scrollableElement.clientHeight -
7066+
top -
7067+
bottom;
70477068
return [
7048-
hasXScrollbar ? snapToPixel(scrollbarWidth) : 0,
7049-
hasYScrollbar ? snapToPixel(scrollbarHeight) : 0,
7069+
scrollbarWidth > 0 ? snapToPixel(scrollbarWidth) : 0,
7070+
scrollbarHeight > 0 ? snapToPixel(scrollbarHeight) : 0,
70507071
];
70517072
};
70527073

0 commit comments

Comments
 (0)