fix iframe height when the viewport is smaller than 450px
why: The iframe used for LTI messages has 450px as minimum height When the user has a viewport smaller than the min-height (450px) and launches a tool in a fullscreen placement, the iframe is not resized previous commit https://gerrit.instructure.com/c/canvas-lms/+/291039/8 ignore PS 9 it got messed up refs INTEROP-7431 flag=none -------------------------------------------------- Test plan -------------------------------------------------- * Compile the CSS and JS. Run: ``` rake canvas:compile_assets_dev ``` * Open the Browser Developer Tools (F12) * Open the Responsive Design Mode * Choose a viewport smaller than 450px * Launch any LTI tool from a fullscreen placement like global navigation * The tool should fit the available height * Exit the Responsive Design Mode and launch the tool from the same placement and the tool must also fit the available height Change-Id: I043c9fb6e3a772f1237ba30d1a59162e3ae6da9a Reviewed-on: https://gerrit.instructure.com/c/canvas-lms/+/292646 Tested-by: Service Cloud Jenkins <svc.cloudjenkins@instructure.com> Reviewed-by: Evan Battaglia <ebattaglia@instructure.com> QA-Review: Evan Battaglia <ebattaglia@instructure.com> QA-Review: Ryan Hawkins <ryan.hawkins@instructure.com> Product-Review: Alexis Nast <alexis.nast@instructure.com>
This commit is contained in:
parent
95963e668a
commit
32a9372888
|
@ -119,7 +119,13 @@ div.content_notice {
|
|||
|
||||
iframe.info_alert_outline {
|
||||
border: 2px solid #0374B5 !important;
|
||||
}
|
||||
}
|
||||
|
||||
body.ic-full-screen-lti-tool iframe.tool_launch {
|
||||
// gets the height of the parent element (div.tool_content_wrapper) which is calculated in
|
||||
// ui/features/external_tools_show/jquery/tool_inline.js
|
||||
min-height: 100%;
|
||||
}
|
||||
|
||||
iframe.tool_launch {
|
||||
min-height: 450px;
|
||||
|
|
|
@ -111,18 +111,30 @@ test('does not resize any other container', () => {
|
|||
equal($('.tool_content_wrapper').height(), 300)
|
||||
})
|
||||
|
||||
test('defaults the resize height to 450px', () => {
|
||||
test('defaults the resize height to 450px if no `#tool_content` is found', () => {
|
||||
document.querySelector('#second-wrapper').className = ''
|
||||
document.querySelectorAll('#tool_content').forEach(element => {
|
||||
element.id = 'another_tool_content'
|
||||
})
|
||||
const launchResizer = new ToolLaunchResizer()
|
||||
launchResizer.resize_tool_content_wrapper()
|
||||
equal($('.tool_content_wrapper').height(), 450)
|
||||
document.querySelectorAll('#another_tool_content').forEach(element => {
|
||||
element.id = 'tool_content'
|
||||
})
|
||||
document.querySelector('#second-wrapper').className = 'tool_content_wrapper'
|
||||
})
|
||||
|
||||
test('defaults the resize height to 450px if non numeric value passed', () => {
|
||||
test('defaults the resize height to 450px if non numeric value passed and no `#tool_content` is found', () => {
|
||||
document.querySelector('#second-wrapper').className = ''
|
||||
document.querySelectorAll('#tool_content').forEach(element => {
|
||||
element.id = 'another_tool_content'
|
||||
})
|
||||
const launchResizer = new ToolLaunchResizer()
|
||||
launchResizer.resize_tool_content_wrapper({a: 1})
|
||||
equal($('.tool_content_wrapper').height(), 450)
|
||||
document.querySelectorAll('#another_tool_content').forEach(element => {
|
||||
element.id = 'tool_content'
|
||||
})
|
||||
document.querySelector('#second-wrapper').className = 'tool_content_wrapper'
|
||||
})
|
||||
|
|
|
@ -17,7 +17,6 @@
|
|||
*/
|
||||
|
||||
import $ from 'jquery'
|
||||
import htmlEscape from 'html-escape'
|
||||
import {trackEvent} from '@canvas/google-analytics'
|
||||
import '@canvas/module-sequence-footer'
|
||||
import MarkAsDone from '@canvas/util/jquery/markAsDone'
|
||||
|
@ -27,10 +26,10 @@ import ready from '@instructure/ready'
|
|||
|
||||
ready(() => {
|
||||
const $toolForm = $('#tool_form')
|
||||
|
||||
const launchToolManually = function() {
|
||||
const $button = $toolForm.find('button')
|
||||
|
||||
|
||||
const launchToolManually = function () {
|
||||
const $button = $toolForm.find('button')
|
||||
|
||||
$toolForm.show()
|
||||
|
||||
// Firefox remembers disabled state after page reloads
|
||||
|
@ -41,14 +40,12 @@ ready(() => {
|
|||
$button.attr('disabled', true).text($button.data('expired_message'))
|
||||
}, 60 * 2.5 * 1000)
|
||||
|
||||
$toolForm.submit(function() {
|
||||
$(this)
|
||||
.find('.load_tab,.tab_loaded')
|
||||
.toggle()
|
||||
})
|
||||
}
|
||||
$toolForm.submit(function () {
|
||||
$(this).find('.load_tab,.tab_loaded').toggle()
|
||||
})
|
||||
}
|
||||
|
||||
const launchToolInNewTab = function() {
|
||||
const launchToolInNewTab = function () {
|
||||
$toolForm.attr('target', '_blank')
|
||||
launchToolManually()
|
||||
}
|
||||
|
@ -62,12 +59,14 @@ ready(() => {
|
|||
$toolForm.removeAttr('target')
|
||||
try {
|
||||
$toolForm.submit()
|
||||
// eslint-disable-next-line no-empty
|
||||
} catch (e) {}
|
||||
break
|
||||
default:
|
||||
// Firefox throws an error when submitting insecure content
|
||||
try {
|
||||
$toolForm.submit()
|
||||
// eslint-disable-next-line no-empty
|
||||
} catch (e) {}
|
||||
|
||||
$('#tool_content').bind('load', () => {
|
||||
|
@ -95,41 +94,65 @@ ready(() => {
|
|||
trackEvent(messageType, toolName, toolPath)
|
||||
|
||||
// Iframe resize handler
|
||||
let $tool_content_wrapper
|
||||
let min_tool_height, canvas_chrome_height
|
||||
const $tool_content_wrapper = $('.tool_content_wrapper')
|
||||
let tool_height, canvas_chrome_height
|
||||
|
||||
const $window = $(window)
|
||||
$tool_content_wrapper = $('.tool_content_wrapper')
|
||||
const toolResizer = new ToolLaunchResizer(min_tool_height)
|
||||
const $tool_content = $('iframe#tool_content')
|
||||
const toolResizer = new ToolLaunchResizer(tool_height)
|
||||
|
||||
const $external_content_info_alerts = $tool_content_wrapper.find(
|
||||
'.before_external_content_info_alert, .after_external_content_info_alert'
|
||||
)
|
||||
|
||||
$external_content_info_alerts.on('focus', function(e) {
|
||||
$external_content_info_alerts.on('focus', function () {
|
||||
$tool_content_wrapper.find('iframe').css('border', '2px solid #0374B5')
|
||||
$(this).removeClass('screenreader-only-tool')
|
||||
})
|
||||
|
||||
$external_content_info_alerts.on('blur', function(e) {
|
||||
$external_content_info_alerts.on('blur', function () {
|
||||
$tool_content_wrapper.find('iframe').css('border', 'none')
|
||||
$(this).addClass('screenreader-only-tool')
|
||||
})
|
||||
|
||||
if (!$('body').hasClass('ic-full-screen-lti-tool')) {
|
||||
const is_full_screen = $('body').hasClass('ic-full-screen-lti-tool')
|
||||
|
||||
if (!is_full_screen) {
|
||||
canvas_chrome_height = $tool_content_wrapper.offset().top + $('#footer').outerHeight(true)
|
||||
}
|
||||
|
||||
// Only calculate height on resize if body does not have
|
||||
// .ic-full-screen-lti-tool class
|
||||
if ($tool_content_wrapper.length && !$('body').hasClass('ic-full-screen-lti-tool')) {
|
||||
if ($tool_content_wrapper.length) {
|
||||
$window
|
||||
.resize(() => {
|
||||
.on('resize', () => {
|
||||
// https://api.jquery.com/resize/
|
||||
// https://developer.mozilla.org/en-US/docs/Web/API/Window/resize_event
|
||||
|
||||
if (!$tool_content_wrapper.data('height_overridden')) {
|
||||
toolResizer.resize_tool_content_wrapper(
|
||||
$window.height() - canvas_chrome_height - $('#sequence_footer').outerHeight(true)
|
||||
)
|
||||
if (is_full_screen) {
|
||||
// divs from app/views/lti/_lti_message.html.erb that usually have 1px
|
||||
const div_before_iframe =
|
||||
document.querySelector('div.before_external_content_info_alert')?.offsetHeight || 0
|
||||
const div_after_iframe =
|
||||
document.querySelector('div.after_external_content_info_alert')?.offsetHeight || 0
|
||||
|
||||
// header#mobile-header
|
||||
// hidden when screen width > 768px
|
||||
// see app/stylesheets/base/_ic_app_header.scss
|
||||
// see https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/offsetHeight
|
||||
const mobile_header_height =
|
||||
document.querySelector('header#mobile-header')?.offsetHeight || 0
|
||||
|
||||
tool_height =
|
||||
window.innerHeight - mobile_header_height - div_before_iframe - div_after_iframe
|
||||
|
||||
toolResizer.resize_tool_content_wrapper(tool_height, $tool_content_wrapper, true)
|
||||
} else {
|
||||
toolResizer.resize_tool_content_wrapper(
|
||||
$window.height() -
|
||||
canvas_chrome_height -
|
||||
// module item navigation from PLAT-1687
|
||||
$('#sequence_footer').outerHeight(true)
|
||||
)
|
||||
}
|
||||
}
|
||||
})
|
||||
.triggerHandler('resize')
|
||||
|
@ -143,7 +166,7 @@ ready(() => {
|
|||
})
|
||||
}
|
||||
|
||||
$('#content').on('click', '#mark-as-done-checkbox', function() {
|
||||
$('#content').on('click', '#mark-as-done-checkbox', function () {
|
||||
MarkAsDone.toggle(this)
|
||||
})
|
||||
})
|
||||
|
|
|
@ -29,18 +29,21 @@ export default class ToolLaunchResizer {
|
|||
|
||||
tool_content_wrapper(wrapperId) {
|
||||
let container = $(`div[data-tool-wrapper-id*='${this.sanitizedWrapperId(wrapperId)}']`)
|
||||
if (container.length <= 0 && $('.tool_content_wrapper').length === 1) {
|
||||
container = $('.tool_content_wrapper')
|
||||
const tool_content_wrapper = $('.tool_content_wrapper')
|
||||
if (container.length <= 0 && tool_content_wrapper.length === 1) {
|
||||
container = tool_content_wrapper
|
||||
}
|
||||
return container
|
||||
}
|
||||
|
||||
resize_tool_content_wrapper(height, container) {
|
||||
resize_tool_content_wrapper(height, container, force_height = false) {
|
||||
let setHeight = height
|
||||
if (typeof setHeight !== 'number') {
|
||||
setHeight = this.minToolHeight
|
||||
}
|
||||
const toolWrapper = container || this.tool_content_wrapper()
|
||||
toolWrapper.height(!height || this.minToolHeight > setHeight ? this.minToolHeight : setHeight)
|
||||
if (force_height) toolWrapper.height(setHeight)
|
||||
else
|
||||
toolWrapper.height(!height || this.minToolHeight > setHeight ? this.minToolHeight : setHeight)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue