Skip to content

Commit 1760c86

Browse files
committed
Fix documentation pages redirect to github.io issues
fix url schema check issue
1 parent 2c9360e commit 1760c86

File tree

2 files changed

+236
-9
lines changed

2 files changed

+236
-9
lines changed

_layouts/default.html

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,17 @@
44
<meta name="description" content="Documentation for Procore developers" />
55
<meta name="viewport" content="width=device-width, initial-scale=1">
66
<meta charset="utf-8">
7+
78
<title>{{ page.title }}</title>
8-
<base target="_parent">
9+
<script>
10+
// Only set base target="_parent" if NOT in an iframe
11+
// This allows iframed pages to navigate within the iframe
12+
if (window.self === window.top) {
13+
var base = document.createElement('base');
14+
base.target = '_parent';
15+
document.head.appendChild(base);
16+
}
17+
</script>
918
<link rel="stylesheet" href="{{ 'assets/css/main.css' | relative_url }}">
1019
<link rel="stylesheet" href="{{ site.baseurl }}/assets/css/nav.css"/>
1120
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.2.0/css/all.min.css">
@@ -23,7 +32,7 @@
2332
<dl class="col_content">
2433
{% for item in section.items %}
2534
<dd{% if item.url == page.url %} class="active"{% endif %}>
26-
<a href="{% if item.absolute != true %}{{ site.url }}{{ site.baseurl }}{% endif %}{{ item.url }}">
35+
<a href="{% if item.absolute == true %}{{ site.url }}{{ site.baseurl }}{{ item.url }}{% else %}{{ item.url | relative_url }}{% endif %}">
2736
<!-- <a href="https://b601-208-127-107-52.ngrok-free.app/documentation{{ item.url }}"> -->
2837
{{ item.title }}
2938
</a>

assets/js/nav.js

Lines changed: 225 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,42 @@
4747
});
4848
// Ensure search results stay on developers.procore.com under /documentation
4949
var basePath = "/documentation";
50+
51+
// Function to rewrite search result links for iframe display
52+
function rewriteSearchResultLinks() {
53+
if (window.self !== window.top) {
54+
try {
55+
var parentOrigin = window.location.ancestorOrigins && window.location.ancestorOrigins.length > 0
56+
? window.location.ancestorOrigins[0]
57+
: document.referrer ? new URL(document.referrer).origin : null;
58+
59+
if (parentOrigin) {
60+
$("#results-container a").each(function() {
61+
var $link = $(this);
62+
var originalHref = $link.attr("href");
63+
64+
// Skip if already processed or special links
65+
if ($link.data("original-href") || !originalHref || originalHref.startsWith("#") || originalHref.startsWith("mailto:") || originalHref.startsWith("javascript:") || originalHref.startsWith("data:") || originalHref.startsWith("vbscript:")) {
66+
return;
67+
}
68+
69+
// Get the path from the href
70+
var path = originalHref;
71+
if (!path.startsWith("/")) {
72+
path = "/" + path;
73+
}
74+
75+
// Store original and set to parent origin for hover display
76+
$link.data("original-href", originalHref);
77+
$link.attr("href", parentOrigin + path);
78+
});
79+
}
80+
} catch (err) {
81+
console.warn("Could not rewrite search result links:", err);
82+
}
83+
}
84+
}
85+
5086
var sjs = SimpleJekyllSearch({
5187
searchInput: document.getElementById("search-input"),
5288
resultsContainer: document.getElementById("results-container"),
@@ -71,26 +107,208 @@
71107
}
72108
return value;
73109
},
110+
noResultsText: "No results found",
111+
limit: 10,
112+
fuzzy: false
74113
});
75-
// Defensive: if a result link is absolute and points off-site, rewrite it to this host
114+
115+
// Use MutationObserver to rewrite search result links when they're added
116+
if (window.self !== window.top) {
117+
var resultsContainer = document.getElementById("results-container");
118+
if (resultsContainer) {
119+
var observer = new MutationObserver(function(mutations) {
120+
rewriteSearchResultLinks();
121+
});
122+
observer.observe(resultsContainer, {
123+
childList: true,
124+
subtree: true
125+
});
126+
}
127+
}
128+
// Handle clicks on search result links - navigate within iframe if in one
76129
$("#results-container").on("click", "a", function (e) {
77-
var href = $(this).attr("href");
78-
if (!href) return;
79-
// Only act on absolute URLs
80-
if (/^https?:\/\//i.test(href)) {
130+
var $link = $(this);
131+
var currentHref = $link.attr("href");
132+
var originalHref = $link.data("original-href");
133+
134+
if (!currentHref) return;
135+
136+
// If in iframe and link points to parent origin, navigate within iframe
137+
if (window.self !== window.top) {
138+
try {
139+
var parentOrigin = window.location.ancestorOrigins && window.location.ancestorOrigins.length > 0
140+
? window.location.ancestorOrigins[0]
141+
: document.referrer ? new URL(document.referrer).origin : null;
142+
143+
if (parentOrigin && currentHref.startsWith(parentOrigin)) {
144+
e.preventDefault();
145+
var path = new URL(currentHref).pathname + new URL(currentHref).search + new URL(currentHref).hash;
146+
// Update iframe location
147+
window.location.href = path;
148+
// Update parent window URL via postMessage (cross-origin safe)
149+
try {
150+
window.parent.postMessage({
151+
type: 'documentationNavigation',
152+
path: path,
153+
fullUrl: parentOrigin + path
154+
}, parentOrigin);
155+
} catch (e) {
156+
console.warn("Could not send navigation message to parent:", e);
157+
}
158+
return false;
159+
}
160+
} catch (err) {
161+
// ignore errors
162+
}
163+
}
164+
165+
// Fallback: handle absolute URLs pointing off-site
166+
if (/^https?:\/\//i.test(currentHref)) {
81167
try {
82-
var u = new URL(href);
168+
var u = new URL(currentHref);
83169
if (u.origin !== window.location.origin) {
84170
e.preventDefault();
85171
var path = u.pathname;
86172
if (!path.startsWith(basePath)) {
87173
path = basePath.replace(/\/$/, "") + "/" + path.replace(/^\//, "");
88174
}
89-
window.location.href = path + (u.search || "") + (u.hash || "");
175+
var newUrl = path + (u.search || "") + (u.hash || "");
176+
window.location.href = newUrl;
177+
return false;
90178
}
91179
} catch (err) {
92180
// ignore malformed URLs
93181
}
94182
}
95183
});
184+
185+
// If in an iframe, rewrite link hrefs for hover display but intercept clicks to navigate within iframe
186+
if (window.self !== window.top) {
187+
try {
188+
var parentOrigin = window.location.ancestorOrigins && window.location.ancestorOrigins.length > 0
189+
? window.location.ancestorOrigins[0]
190+
: document.referrer ? new URL(document.referrer).origin : null;
191+
192+
if (parentOrigin) {
193+
// Function to get the actual path from a href
194+
function getPathFromHref(href) {
195+
if (!href || href.startsWith("#") || href.startsWith("mailto:") || href.startsWith("javascript:") || href.startsWith("data:") || href.startsWith("vbscript:")) {
196+
return null;
197+
}
198+
try {
199+
if (href.match(/^https?:\/\//)) {
200+
return new URL(href).pathname + new URL(href).search + new URL(href).hash;
201+
} else {
202+
// Relative URL
203+
return href.startsWith("/") ? href : "/" + href;
204+
}
205+
} catch (e) {
206+
return href.startsWith("/") ? href : "/" + href;
207+
}
208+
}
209+
210+
// Rewrite navigation links for hover display
211+
$("nav a").each(function() {
212+
var $link = $(this);
213+
var originalHref = $link.attr("href");
214+
var path = getPathFromHref(originalHref);
215+
216+
if (path && !path.startsWith("#") && !path.startsWith("mailto:") && !path.startsWith("javascript:") && !path.startsWith("data:") && !path.startsWith("vbscript:")) {
217+
// Store original href in data attribute
218+
$link.data("original-href", originalHref);
219+
// Set href to parent origin for hover display
220+
$link.attr("href", parentOrigin + path);
221+
}
222+
});
223+
224+
// Rewrite links in main content area for hover display
225+
$("main a").each(function() {
226+
var $link = $(this);
227+
var originalHref = $link.attr("href");
228+
var path = getPathFromHref(originalHref);
229+
230+
if (path && !path.startsWith("#") && !path.startsWith("mailto:") && !path.startsWith("javascript:") && !path.startsWith("data:") && !path.startsWith("vbscript:")) {
231+
// Store original href in data attribute
232+
$link.data("original-href", originalHref);
233+
// Set href to parent origin for hover display
234+
$link.attr("href", parentOrigin + path);
235+
}
236+
});
237+
238+
// Intercept clicks on navigation and content links to navigate within iframe
239+
$(document).on("click", "nav a, main a", function(e) {
240+
var $link = $(this);
241+
var originalHref = $link.data("original-href");
242+
var currentHref = $link.attr("href");
243+
244+
// If we have a stored original href, use it; otherwise check current href
245+
var hrefToUse = originalHref || currentHref;
246+
247+
// Skip external links, anchors, and special protocols
248+
if (!hrefToUse || hrefToUse.startsWith("#") || hrefToUse.startsWith("mailto:") || hrefToUse.startsWith("javascript:") || hrefToUse.startsWith("data:") || hrefToUse.startsWith("vbscript:")) {
249+
return; // Let default behavior handle these
250+
}
251+
252+
// If current href points to parent origin (for display), navigate using the path within iframe
253+
if (currentHref && currentHref.startsWith(parentOrigin)) {
254+
e.preventDefault();
255+
var path = new URL(currentHref).pathname + new URL(currentHref).search + new URL(currentHref).hash;
256+
// Update iframe location
257+
window.location.href = path;
258+
// Update parent window URL via postMessage (cross-origin safe)
259+
try {
260+
window.parent.postMessage({
261+
type: 'documentationNavigation',
262+
path: path,
263+
fullUrl: parentOrigin + path
264+
}, parentOrigin);
265+
} catch (e) {
266+
console.warn("Could not send navigation message to parent:", e);
267+
}
268+
return false;
269+
} else if (hrefToUse.match(/^https?:\/\//) && !hrefToUse.startsWith(window.location.origin) && !hrefToUse.startsWith(parentOrigin)) {
270+
// External link (not parent origin, not current origin) - let it open normally
271+
return;
272+
} else if (originalHref && originalHref.startsWith(parentOrigin)) {
273+
// Original href was parent origin - navigate within iframe
274+
e.preventDefault();
275+
var path = new URL(originalHref).pathname + new URL(originalHref).search + new URL(originalHref).hash;
276+
// Update iframe location
277+
window.location.href = path;
278+
// Update parent window URL via postMessage (cross-origin safe)
279+
try {
280+
window.parent.postMessage({
281+
type: 'documentationNavigation',
282+
path: path,
283+
fullUrl: parentOrigin + path
284+
}, parentOrigin);
285+
} catch (e) {
286+
console.warn("Could not send navigation message to parent:", e);
287+
}
288+
return false;
289+
} else if (hrefToUse && !hrefToUse.match(/^https?:\/\//)) {
290+
// Relative link - navigate within iframe and update parent URL
291+
e.preventDefault();
292+
var path = hrefToUse.startsWith("/") ? hrefToUse : "/" + hrefToUse;
293+
// Update iframe location
294+
window.location.href = path;
295+
// Update parent window URL via postMessage (cross-origin safe)
296+
try {
297+
window.parent.postMessage({
298+
type: 'documentationNavigation',
299+
path: path,
300+
fullUrl: parentOrigin + path
301+
}, parentOrigin);
302+
} catch (e) {
303+
console.warn("Could not send navigation message to parent:", e);
304+
}
305+
return false;
306+
}
307+
// For other cases, let default behavior work
308+
});
309+
}
310+
} catch (err) {
311+
console.warn("Could not rewrite links for parent origin:", err);
312+
}
313+
}
96314
})();

0 commit comments

Comments
 (0)