From 82ca471c5b45359b1b39ce8ef69cf26544b39356 Mon Sep 17 00:00:00 2001 From: Albert Gasset Date: Mon, 8 Oct 2018 09:49:41 +0200 Subject: [PATCH 1/3] MOBILE-2650 utils: Fix links inside iframes created after page load --- src/providers/utils/iframe.ts | 90 ++++++++++++++++------------------- 1 file changed, 42 insertions(+), 48 deletions(-) diff --git a/src/providers/utils/iframe.ts b/src/providers/utils/iframe.ts index 7bcbf00b2..55cbd8304 100644 --- a/src/providers/utils/iframe.ts +++ b/src/providers/utils/iframe.ts @@ -183,55 +183,49 @@ export class CoreIframeUtilsProvider { return; } - const links = Array.from(contentDocument.querySelectorAll('a')); - links.forEach((el: HTMLAnchorElement) => { - const href = el.href; + contentDocument.addEventListener('click', (event) => { + if (event.defaultPrevented) { + // Event already prevented by some other code. + return; + } - // Check that href is not null. - if (href) { - const scheme = this.urlUtils.getUrlScheme(href); - if (scheme && scheme == 'javascript') { - // Javascript links should be treated by the iframe's Javascript. - // There's nothing to be done with these links, so they'll be ignored. - return; - } else if (scheme && scheme != 'file' && scheme != 'filesystem') { - // Scheme suggests it's an external resource, open it in browser. - el.addEventListener('click', (e) => { - // If the link's already prevented by SCORM JS then we won't open it in browser. - if (!e.defaultPrevented) { - e.preventDefault(); - if (!this.sitesProvider.isLoggedIn()) { - this.utils.openInBrowser(href); - } else { - this.sitesProvider.getCurrentSite().openInBrowserWithAutoLoginIfSameSite(href); - } - } - }); - } else if (el.target == '_parent' || el.target == '_top' || el.target == '_blank') { - // Opening links with _parent, _top or _blank can break the app. We'll open it in InAppBrowser. - el.addEventListener('click', (e) => { - // If the link's already prevented by SCORM JS then we won't open it in InAppBrowser. - if (!e.defaultPrevented) { - e.preventDefault(); - this.utils.openFile(href).catch((error) => { - this.domUtils.showErrorModal(error); - }); - } - }); - } else if (this.platform.is('ios') && (!el.target || el.target == '_self')) { - // In cordova ios 4.1.0 links inside iframes stopped working. We'll manually treat them. - el.addEventListener('click', (e) => { - // If the link's already prevented by SCORM JS then we won't treat it. - if (!e.defaultPrevented) { - if (element.tagName.toLowerCase() == 'object') { - e.preventDefault(); - element.setAttribute('data', href); - } else { - e.preventDefault(); - element.setAttribute('src', href); - } - } - }); + // Find the link being clicked. + let el = event.target; + while (el && el.tagName !== 'A') { + el = el.parentElement; + } + if (!el || el.tagName !== 'A') { + return; + } + const link = el; + + const scheme = this.urlUtils.getUrlScheme(link.href); + if (!link.href || (scheme && scheme == 'javascript')) { + // Links with no URL and Javascript links are ignored. + return; + } + + if (scheme && scheme != 'file' && scheme != 'filesystem') { + // Scheme suggests it's an external resource, open it in browser. + event.preventDefault(); + if (!this.sitesProvider.isLoggedIn()) { + this.utils.openInBrowser(link.href); + } else { + this.sitesProvider.getCurrentSite().openInBrowserWithAutoLoginIfSameSite(link.href); + } + } else if (link.target == '_parent' || link.target == '_top' || link.target == '_blank') { + // Opening links with _parent, _top or _blank can break the app. We'll open it in InAppBrowser. + event.preventDefault(); + this.utils.openFile(link.href).catch((error) => { + this.domUtils.showErrorModal(error); + }); + } else if (this.platform.is('ios') && (!link.target || link.target == '_self')) { + // In cordova ios 4.1.0 links inside iframes stopped working. We'll manually treat them. + event.preventDefault(); + if (element.tagName.toLowerCase() == 'object') { + element.setAttribute('data', link.href); + } else { + element.setAttribute('src', link.href); } } }); From ab8fddaaf340c3380beff10136c663a2287fe2b0 Mon Sep 17 00:00:00 2001 From: Albert Gasset Date: Mon, 8 Oct 2018 16:29:35 +0200 Subject: [PATCH 2/3] MOBILE-2650 utils: Do not create Window objects, it throws an exception --- src/providers/utils/iframe.ts | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/providers/utils/iframe.ts b/src/providers/utils/iframe.ts index 55cbd8304..504bdb3ae 100644 --- a/src/providers/utils/iframe.ts +++ b/src/providers/utils/iframe.ts @@ -102,12 +102,12 @@ export class CoreIframeUtilsProvider { } else { this.logger.warn('Cannot get iframe dir path to open relative url', url, element); - return new Window(); // Return new Window object. + return null; } } else { this.logger.warn('Cannot get iframe src to open relative url', url, element); - return new Window(); // Return new Window object. + return null; } } @@ -126,7 +126,8 @@ export class CoreIframeUtilsProvider { } } - return new Window(); // Return new Window object. + // We cannot create new Window objects directly, return null which is a valid return value for Window.open(). + return null; }; } From 85c3d0fc7cc6169ae4be6465d8f40f963ba61813 Mon Sep 17 00:00:00 2001 From: Albert Gasset Date: Tue, 9 Oct 2018 16:29:11 +0200 Subject: [PATCH 3/3] MOBILE-2650 format-text: Treat limks in Vimeo and Youtube iframes --- src/directives/format-text.ts | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/directives/format-text.ts b/src/directives/format-text.ts index 817e88360..2c46e20f4 100644 --- a/src/directives/format-text.ts +++ b/src/directives/format-text.ts @@ -519,6 +519,8 @@ export class CoreFormatTextDirective implements OnChanges { // Replace video tag by the iframe. video.parentNode.replaceChild(iframe, video); + + this.iframeUtils.treatFrame(iframe); } /** @@ -554,7 +556,7 @@ export class CoreFormatTextDirective implements OnChanges { * * @param {HTMLIFrameElement} iframe Iframe to treat. * @param {CoreSite} site Site instance. - * @param {Boolean} canTreatVimeo Whether Vimeo videos can be treated in the site. + * @param {boolean} canTreatVimeo Whether Vimeo videos can be treated in the site. */ protected treatIframe(iframe: HTMLIFrameElement, site: CoreSite, canTreatVimeo: boolean): void { const src = iframe.src, @@ -571,8 +573,9 @@ export class CoreFormatTextDirective implements OnChanges { }); return; + } - } else if (src && canTreatVimeo) { + if (src && canTreatVimeo) { // Check if it's a Vimeo video. If it is, use the wsplayer script instead to make restricted videos work. const matches = iframe.src.match(/https?:\/\/player\.vimeo\.com\/video\/([0-9]+)/); if (matches && matches[1]) { @@ -620,8 +623,6 @@ export class CoreFormatTextDirective implements OnChanges { } }); } - - return; } }