// (C) Copyright 2015 Moodle Pty Ltd. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. (function () { var url = location.href; if (url.match(/^moodleappfs:\/\/localhost/i) || !url.match(/^[a-z0-9]+:\/\//i)) { // Same domain as the app, stop. return; } // Redefine window.open. window.open = function(url, name, specs) { if (name == '_self') { // Link should be loaded in the same frame. location.href = toAbsolute(url); return; } getRootWindow(window).postMessage({ environment: 'moodleapp', context: 'iframe', action: 'window_open', frameUrl: location.href, url: url, name: name, specs: specs, }, '*'); }; // Handle link clicks. document.addEventListener('click', (event) => { if (event.defaultPrevented) { // Event already prevented by some other code. return; } // Find the link being clicked. var el = event.target; while (el && (el.tagName !== 'A' && el.tagName !== 'a')) { el = el.parentElement; } if (!el || el.treated) { return; } // Add click listener to the link, this way if the iframe has added a listener to the link it will be executed first. el.treated = true; el.addEventListener('click', function(event) { linkClicked(el, event); }); }, { capture: true // Use capture to fix this listener not called if the element clicked is too deep in the DOM. }); /** * Concatenate two paths, adding a slash between them if needed. * * @param leftPath Left path. * @param rightPath Right path. * @return Concatenated path. */ function concatenatePaths(leftPath, rightPath) { if (!leftPath) { return rightPath; } else if (!rightPath) { return leftPath; } var lastCharLeft = leftPath.slice(-1); var firstCharRight = rightPath.charAt(0); if (lastCharLeft === '/' && firstCharRight === '/') { return leftPath + rightPath.substr(1); } else if (lastCharLeft !== '/' && firstCharRight !== '/') { return leftPath + '/' + rightPath; } else { return leftPath + rightPath; } } /** * Get the root window. * * @param win Current window to check. * @return Root window. */ function getRootWindow(win) { if (win.parent === win) { return win; } return getRootWindow(win.parent); } /** * Get the scheme from a URL. * * @param url URL to treat. * @return Scheme, undefined if no scheme found. */ function getUrlScheme(url) { if (!url) { return; } var matches = url.match(/^([a-z][a-z0-9+\-.]*):/); if (matches && matches[1]) { return matches[1]; } } /** * Check if a URL is absolute. * * @param url URL to treat. * @return Whether it's absolute. */ function isAbsoluteUrl(url) { return /^[^:]{2,}:\/\//i.test(url); } /** * Check whether a URL scheme belongs to a local file. * * @param scheme Scheme to check. * @return Whether the scheme belongs to a local file. */ function isLocalFileUrlScheme(scheme) { if (scheme) { scheme = scheme.toLowerCase(); } return scheme == 'cdvfile' || scheme == 'file' || scheme == 'filesystem' || scheme == 'moodleappfs'; } /** * Handle a click on an anchor element. * * @param link Anchor element clicked. * @param event Click event. */ function linkClicked(link, event) { if (event.defaultPrevented) { // Event already prevented by some other code. return; } var linkScheme = getUrlScheme(link.href); var pageScheme = getUrlScheme(location.href); var isTargetSelf = !link.target || link.target == '_self'; if (!link.href || linkScheme == 'javascript') { // Links with no URL and Javascript links are ignored. return; } event.preventDefault(); if (isTargetSelf && (isLocalFileUrlScheme(linkScheme) || !isLocalFileUrlScheme(pageScheme))) { // Link should be loaded in the same frame. Don't do it if link is online and frame is local. location.href = toAbsolute(link.href); return; } getRootWindow(window).postMessage({ environment: 'moodleapp', context: 'iframe', action: 'link_clicked', frameUrl: location.href, link: { href: link.href, target: link.target, originalHref: link.getAttribute('href'), }, }, '*'); } /** * Convert a URL to an absolute URL if needed using the frame src. * * @param url URL to convert. * @return Absolute URL. */ function toAbsolute(url) { if (isAbsoluteUrl(url)) { return url; } // It's a relative URL, use the frame src to create the full URL. var pathToDir = location.href.substring(0, location.href.lastIndexOf('/')); return concatenatePaths(pathToDir, url); } })();