В настоящее время я работаю над небольшим проектом по созданию блестящего приложения для систематизированных c обзоров литургий, и как часть этого я добавил функциональность для загрузки pdf-файлов и затем показываю их внутри iframe (pdf показывает внутри iframe, как и ожидалось). В качестве следующего шага я хочу иметь возможность выбрать текст в этом PDF и использовать Javascript, чтобы автоматически скопировать его в textAreaInput
в родительском фрейме. Теперь проблема в том, что консоль моего браузера выдает мне эту ошибку:
SecurityError: Permission denied to access property "document" on cross-origin object
Поэтому я изначально думал, что это всего лишь вопрос хранения файла PDF в неправильном месте ( см. это обсуждение ), но у меня myPdf.pdf
уже сохранено в папке www
(см. структуру папок ниже). Еще одна странная вещь, которая заставляет меня сомневаться в том, что это происходит только тогда, когда я встраиваю myPdf.pdf
в iframe, но когда я встраиваю myHtml.html
, я не получаю эту ошибку, и функция работает, как ожидалось (кроме незначительной проблемы, которую я нужно щелкнуть за пределами iframe, чтобы вызвать функцию, но это еще одна проблема на следующий день).
Любая помощь для решения этой проблемы высоко ценится (намеки на это странное поведение также приветствуются)
Шаги для воспроизведения:
- настроить каталог, как показано в разделе Структура папок ниже
- Откройте R-Studio и запустите приложение, выполнив весь код
- Открыть консоль браузера
- В веб-браузере отметьте текст внутри фрейма
- Сфокусируйте родительский фрейм, нажав за пределами фрейма
- Нажмите и отпустите
Enter
, чтобы активировать функцию javascript (Теперь вы должны увидеть отмеченный текст внутри textAreaInput
в родительском элементе - Остановить блестящее приложение и изменить Источник
tags$iframe()
в App.R, закомментировав текущий и раскомментировав предыдущий - Повторите шаги 2-6, чтобы увидеть ошибку консоли
Структура папки
ShinyAppFolder
|──app.R
|──www/
| |──js/
| | |──getTextFromIframe.js
| |──myHtml.html
| |──myPdf.pdf
| |──cachedFiles
Shiny App.R
library(shiny)
wwwPath <- paste0(getwd(),"/www")
addResourcePath("localfiles", wwwPath)
# fulltext::cache_options_set(full_path = paste0(wwwPath, "/cachedFiles"))
fileName <- "myPdf.pdf"
ui <- fluidPage(
headerPanel(h3("systematicReviewR")),
sidebarLayout(
sidebarPanel(
width = 4,
textAreaInput("markedTextFromPdf", label = "Test, if I can copy text from iframed local pdf"),
includeScript("www/js/getTextFromIframe.js")
),
mainPanel(
htmlOutput("pdfviewer")
)
)
)
server <- function(input, output, session) {
output$pdfviewer <- renderUI({
tags$iframe(id = "localFile",
style = "height: 600px; width: 100%; scrolling = yes",
# src = paste0("localfiles/", fileName)
src = "localfiles/myHtml.html"
)
})
}
shinyApp(ui = ui, server = server)
Javascript getTextFromIframe. js
Вот код для моего javascript файла:
function myFunction() {
var myIframe = document.getElementById('localFile');
console.log(myIframe);
var idoc = myIframe.contentDocument || myIframe.contentWindow.document; // ie compatibility
var text = idoc.getSelection().toString();
return(text);
}
onkeyup = function(e) {
if (e.which ==13) {
var selection = myFunction();
var parentDocument = window.parent.document;
var parentTextbox = parentDocument.getElementById("markedTextFromPdf");
parentTextbox.textContent = parentTextbox.textContent + selection;
// based on: https://www.youtube.com/watch?v=6NNe6GWO8us
//Shiny.setInputValue("getTextFromIframe", selection);
console.log(parentTextbox);
}
}