move RCE's makeAllExternalLinksExternalLinks
Change-Id: I4471750caf9f13220471f3a5af7f983eaf5c3b08 Reviewed-on: https://gerrit.instructure.com/c/canvas-lms/+/339255 Tested-by: Service Cloud Jenkins <svc.cloudjenkins@instructure.com> Reviewed-by: Samuel Lee <samuel.lee@instructure.com> QA-Review: Aaron Shafovaloff <ashafovaloff@instructure.com> Product-Review: Aaron Shafovaloff <ashafovaloff@instructure.com>
This commit is contained in:
parent
3135c83e1f
commit
863eed6c6f
|
@ -16,17 +16,17 @@
|
||||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import {IconDownloadLine, IconExternalLinkLine} from '@instructure/ui-icons/es/svg'
|
import {IconDownloadLine} from '@instructure/ui-icons/es/svg'
|
||||||
import formatMessage from '../format-message'
|
import formatMessage from '../format-message'
|
||||||
import {closest, getData, hide, insertAfter, setData, show} from './jqueryish_funcs'
|
import {closest, getData, hide, insertAfter, setData, show} from './jqueryish_funcs'
|
||||||
import {getTld, isExternalLink, showFilePreview, youTubeID} from './instructure_helper'
|
import {isExternalLink, showFilePreview, youTubeID} from './instructure_helper'
|
||||||
import mediaCommentThumbnail from './media_comment_thumbnail'
|
import mediaCommentThumbnail from './media_comment_thumbnail'
|
||||||
import {addParentFrameContextToUrl} from '../rce/plugins/instructure_rce_external_tools/util/addParentFrameContextToUrl'
|
import {addParentFrameContextToUrl} from '../rce/plugins/instructure_rce_external_tools/util/addParentFrameContextToUrl'
|
||||||
import {MathJaxDirective, Mathml} from './mathml'
|
import {MathJaxDirective, Mathml} from './mathml'
|
||||||
|
import {makeExternalLinkIcon} from './external_links'
|
||||||
|
|
||||||
// in jest the es directory doesn't exist so stub the undefined svg
|
// in jest the es directory doesn't exist so stub the undefined svg
|
||||||
const IconDownloadSVG = IconDownloadLine?.src || '<svg></svg>'
|
const IconDownloadSVG = IconDownloadLine?.src || '<svg></svg>'
|
||||||
const IconExternalLinkSVG = IconExternalLinkLine?.src || '<svg></svg>'
|
|
||||||
|
|
||||||
function makeDownloadButton(download_url, filename) {
|
function makeDownloadButton(download_url, filename) {
|
||||||
const a = document.createElement('a')
|
const a = document.createElement('a')
|
||||||
|
@ -53,28 +53,6 @@ function makeDownloadButton(download_url, filename) {
|
||||||
return a
|
return a
|
||||||
}
|
}
|
||||||
|
|
||||||
function makeExternalLinkIcon(forLink) {
|
|
||||||
const dir = (forLink && window.getComputedStyle(forLink).direction) || 'ltr'
|
|
||||||
const $icon = document.createElement('span')
|
|
||||||
$icon.setAttribute('class', 'external_link_icon')
|
|
||||||
const style = `margin-inline-start: 5px; display: inline-block; text-indent: initial; ${
|
|
||||||
dir === 'rtl' ? 'transform:scale(-1, 1)' : ''
|
|
||||||
}`
|
|
||||||
$icon.setAttribute('style', style)
|
|
||||||
$icon.setAttribute('role', 'presentation')
|
|
||||||
$icon.innerHTML = IconExternalLinkSVG
|
|
||||||
$icon.firstChild.setAttribute(
|
|
||||||
'style',
|
|
||||||
'width:1em; height:1em; vertical-align:middle; fill:currentColor'
|
|
||||||
)
|
|
||||||
|
|
||||||
const srspan = document.createElement('span')
|
|
||||||
srspan.setAttribute('class', 'screenreader-only')
|
|
||||||
srspan.textContent = formatMessage('Links to an external site.')
|
|
||||||
$icon.appendChild(srspan)
|
|
||||||
return $icon
|
|
||||||
}
|
|
||||||
|
|
||||||
function handleYoutubeLink($link) {
|
function handleYoutubeLink($link) {
|
||||||
const href = $link.getAttribute('href')
|
const href = $link.getAttribute('href')
|
||||||
const id = youTubeID(href || '')
|
const id = youTubeID(href || '')
|
||||||
|
@ -400,39 +378,3 @@ export function enhanceUserContent(container = document, opts = {}) {
|
||||||
frame.src = src
|
frame.src = src
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
export function makeAllExternalLinksExternalLinks() {
|
|
||||||
// in 100ms (to give time for everything else to load), find all the external links and add give them
|
|
||||||
// the external link look and behavior (force them to open in a new tab)
|
|
||||||
setTimeout(function () {
|
|
||||||
const content = document.getElementById('content')
|
|
||||||
if (!content) return
|
|
||||||
const tld = getTld(window.location.hostname)
|
|
||||||
const links = content.querySelectorAll(`a[href*="//"]:not([href*="${tld}"])`) // technique for finding "external" links copied from https://davidwalsh.name/external-links-css
|
|
||||||
for (let i = 0; i < links.length; i++) {
|
|
||||||
const $link = links[i]
|
|
||||||
// don't mess with the ones that were already processed in enhanceUserContent
|
|
||||||
if ($link.classList.contains('external')) continue
|
|
||||||
if ($link.matches('.open_in_a_new_tab')) continue
|
|
||||||
if ($link.querySelectorAll('img').length > 0) continue
|
|
||||||
if ($link.matches('.not_external')) continue
|
|
||||||
if ($link.matches('.exclude_external_icon')) continue
|
|
||||||
// we have some pre-instui buttons that are styled links
|
|
||||||
if ($link.classList.contains('btn')) continue
|
|
||||||
const $linkToReplace = $link
|
|
||||||
if ($linkToReplace) {
|
|
||||||
const $linkIndicator = makeExternalLinkIcon()
|
|
||||||
$linkToReplace.classList.add('external')
|
|
||||||
$linkToReplace.querySelectorAll('span.ui-icon-extlink').forEach(c => c.remove)
|
|
||||||
$linkToReplace.setAttribute('target', '_blank')
|
|
||||||
$linkToReplace.setAttribute('rel', 'noreferrer noopener')
|
|
||||||
const $linkSpan = document.createElement('span')
|
|
||||||
const $linkText = $linkToReplace.innerHTML
|
|
||||||
$linkSpan.innerHTML = $linkText
|
|
||||||
while ($linkToReplace.firstChild) $linkToReplace.removeChild($linkToReplace.firstChild)
|
|
||||||
$linkToReplace.appendChild($linkSpan)
|
|
||||||
$linkToReplace.appendChild($linkIndicator)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}, 100)
|
|
||||||
}
|
|
||||||
|
|
|
@ -0,0 +1,81 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2011 - present Instructure, Inc.
|
||||||
|
*
|
||||||
|
* This file is part of Canvas.
|
||||||
|
*
|
||||||
|
* Canvas is free software: you can redistribute it and/or modify it under
|
||||||
|
* the terms of the GNU Affero General Public License as published by the Free
|
||||||
|
* Software Foundation, version 3 of the License.
|
||||||
|
*
|
||||||
|
* Canvas is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
|
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||||
|
* A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
|
||||||
|
* details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License along
|
||||||
|
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import {IconExternalLinkLine} from '@instructure/ui-icons/es/svg'
|
||||||
|
import {getTld} from './instructure_helper'
|
||||||
|
import formatMessage from '../format-message'
|
||||||
|
|
||||||
|
const IconExternalLinkSVG = IconExternalLinkLine?.src || '<svg></svg>'
|
||||||
|
|
||||||
|
export function makeExternalLinkIcon(forLink) {
|
||||||
|
const dir = (forLink && window.getComputedStyle(forLink).direction) || 'ltr'
|
||||||
|
const $icon = document.createElement('span')
|
||||||
|
$icon.setAttribute('class', 'external_link_icon')
|
||||||
|
const style = `margin-inline-start: 5px; display: inline-block; text-indent: initial; ${
|
||||||
|
dir === 'rtl' ? 'transform:scale(-1, 1)' : ''
|
||||||
|
}`
|
||||||
|
$icon.setAttribute('style', style)
|
||||||
|
$icon.setAttribute('role', 'presentation')
|
||||||
|
$icon.innerHTML = IconExternalLinkSVG
|
||||||
|
$icon.firstChild.setAttribute(
|
||||||
|
'style',
|
||||||
|
'width:1em; height:1em; vertical-align:middle; fill:currentColor'
|
||||||
|
)
|
||||||
|
|
||||||
|
const srspan = document.createElement('span')
|
||||||
|
srspan.setAttribute('class', 'screenreader-only')
|
||||||
|
srspan.textContent = formatMessage('Links to an external site.')
|
||||||
|
$icon.appendChild(srspan)
|
||||||
|
return $icon
|
||||||
|
}
|
||||||
|
|
||||||
|
export function makeAllExternalLinksExternalLinks() {
|
||||||
|
// in 100ms (to give time for everything else to load), find all the external links and add give them
|
||||||
|
// the external link look and behavior (force them to open in a new tab)
|
||||||
|
setTimeout(function () {
|
||||||
|
const content = document.getElementById('content')
|
||||||
|
if (!content) return
|
||||||
|
const tld = getTld(window.location.hostname)
|
||||||
|
const links = content.querySelectorAll(`a[href*="//"]:not([href*="${tld}"])`) // technique for finding "external" links copied from https://davidwalsh.name/external-links-css
|
||||||
|
for (let i = 0; i < links.length; i++) {
|
||||||
|
const $link = links[i]
|
||||||
|
// don't mess with the ones that were already processed in enhanceUserContent
|
||||||
|
if ($link.classList.contains('external')) continue
|
||||||
|
if ($link.matches('.open_in_a_new_tab')) continue
|
||||||
|
if ($link.querySelectorAll('img').length > 0) continue
|
||||||
|
if ($link.matches('.not_external')) continue
|
||||||
|
if ($link.matches('.exclude_external_icon')) continue
|
||||||
|
// we have some pre-instui buttons that are styled links
|
||||||
|
if ($link.classList.contains('btn')) continue
|
||||||
|
const $linkToReplace = $link
|
||||||
|
if ($linkToReplace) {
|
||||||
|
const $linkIndicator = makeExternalLinkIcon()
|
||||||
|
$linkToReplace.classList.add('external')
|
||||||
|
$linkToReplace.querySelectorAll('span.ui-icon-extlink').forEach(c => c.remove)
|
||||||
|
$linkToReplace.setAttribute('target', '_blank')
|
||||||
|
$linkToReplace.setAttribute('rel', 'noreferrer noopener')
|
||||||
|
const $linkSpan = document.createElement('span')
|
||||||
|
const $linkText = $linkToReplace.innerHTML
|
||||||
|
$linkSpan.innerHTML = $linkText
|
||||||
|
while ($linkToReplace.firstChild) $linkToReplace.removeChild($linkToReplace.firstChild)
|
||||||
|
$linkToReplace.appendChild($linkSpan)
|
||||||
|
$linkToReplace.appendChild($linkIndicator)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, 100)
|
||||||
|
}
|
|
@ -22,7 +22,8 @@ import {uniqueId} from 'lodash'
|
||||||
import htmlEscape from '@instructure/html-escape'
|
import htmlEscape from '@instructure/html-escape'
|
||||||
import {showFlashAlert} from '@canvas/alerts/react/FlashAlert'
|
import {showFlashAlert} from '@canvas/alerts/react/FlashAlert'
|
||||||
import RichContentEditor from '@canvas/rce/RichContentEditor'
|
import RichContentEditor from '@canvas/rce/RichContentEditor'
|
||||||
import {enhanceUserContent, makeAllExternalLinksExternalLinks} from '@instructure/canvas-rce'
|
import {enhanceUserContent} from '@instructure/canvas-rce'
|
||||||
|
import {makeAllExternalLinksExternalLinks} from '@instructure/canvas-rce/es/enhance-user-content/external_links'
|
||||||
import './instructure_helper'
|
import './instructure_helper'
|
||||||
import 'jqueryui/draggable'
|
import 'jqueryui/draggable'
|
||||||
import '@canvas/jquery/jquery.ajaxJSON'
|
import '@canvas/jquery/jquery.ajaxJSON'
|
||||||
|
|
Loading…
Reference in New Issue