Как получить выбор пользователя в документах Microsoft Word Online
Я создаю расширение Chrome, которое должно взаимодействовать с выбором пользователя в документах Microsoft Word Online - добавить новое выделение вместо выделения естественного выделения и затем удалить его. Проблема в том, что я не могу получить выбор пользователя: ответ на window.getSelection()
возвращает результат, как будто выбор пуст
Вот файлы с моим расширением:
manifest.json
{
"manifest_version": 2,
"name": "The extension name",
"version": "1.0",
"description": "This extension description",
"browser_action": {
"default_icon": "icon.png",
"default_popup": "popup.html"
},
"icons": {
"128": "icon.png"
},
"content_scripts": [{
"matches": ["<all_urls>"],
"js": ["content_script.js"],
"run_at": "document_end",
"all_frames": true
}],
"permissions": ["activeTab"]
}
popup.html
<!doctype html>
<html>
<head>
<script src="popup.js"></script>
</head>
<body>
<div id="wrapper">
<form id="settings" name="settings">
<div id="apply" class="form-row">
<input type="submit" name="apply" value="Apply"/>
</div>
</form>
</div>
</body>
</html>
popup.js
document.addEventListener('DOMContentLoaded', function() {
document.getElementById("settings").addEventListener("submit", function (e) {
e.preventDefault();
chrome.tabs.executeScript(null, {file: 'toolbar.js'}, function() {
chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
chrome.tabs.sendMessage(tabs[0].id, {});
});
);
}, false);
});
toolbar.js
function showToolbar() {
var dom_body = document.getElementsByTagName('body')[0];
var tb_wrapper = document.createElement('div');
tb_wrapper.id = "toolbar_wrapper";
var tb_toolbar_play = document.createElement('button');
tb_toolbar_play.id = "toolbar_play";
tb_toolbar_play.title = "Play";
tb_toolbar_play.value = "Play";
tb_wrapper.appendChild(tb_toolbar_play);
dom_body.appendChild(tb_wrapper);
}
showToolbar();
content_script.js
function playButtonOnClickEventListener(request, sender, sendResponse) {
var toolbar = document.getElementById("toolbar_wrapper");
if (toolbar !== null) {
var toolbar_play_button = document.getElementById("toolbar_play");
toolbar_play_button.addEventListener("click", function (e) {
var selection = window.getSelection();
console.log(selection);
});
}
sendResponse({data: "response", success: true});
}
chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) {
playButtonOnClickEventListener(request, sender, sendResponse);
});
Итак, что я хочу увидеть в инструментах Chrome Developer после console.log(selection)
выполняет:
PS Расширение отлично работает с Google Docs.
2 ответа
Вот решение проблемы. Надеюсь, что это может быть полезно для кого-то однажды.
В настоящее время я вижу всю картину по-другому, поэтому я изменил количество файлов и их содержимое.
manifest.json
{
"manifest_version": 2,
"version": "1.1.1",
"name": "Test name",
"description": "Test description",
"browser_action": {
"default_icon": "icon.png"
},
"icons": {
"128": "icon.png"
},
"content_scripts": [
{
"matches": ["<all_urls>"],
"js": ["content_script.js"],
"run_at": "document_end",
"all_frames": true
}
],
"permissions": ["activeTab"]
}
content_script.js
//Word Online pages contain several different iframes, so, in order
//to find the one where the text that we are going to work with
//is placed, we have to use the Chrome Runtime API and its
//"sendMessage" method that works in every frame.
//https://developer.chrome.com/apps/runtime#method-sendMessage
chrome.runtime.sendMessage("", function() {
if (checkFrameLocation()) {
showToolbar();
}
});
function checkFrameLocation() {
//So as I work with documents in OneDrive (onedrive.live.com)
//and in Sharepoint (<USER_NAME>-my.shrepoint.com), I found out
//that I need iframes with these URLs only.
var trusted_urls = [
"https://euc-word-edit.officeapps.live.com",
"https://word-edit.officeapps.live.com",
"nl1-word-edit.officeapps.live.com"
];
var result = false;
for (var i = 0; i < trusted_urls.length; i++) {
if (window.location.href.indexOf(trusted_urls[i]) > -1) {
result = true;
}
}
return result;
}
function showToolbar() {
var dom_body = document.body;
var tb_wrapper = document.createElement('div');
tb_wrapper.id = "toolbar_wrapper";
tb_wrapper.style.position = "absolute";
tb_wrapper.style.top = "200px";
tb_wrapper.style.left = "200px";
tb_wrapper.style.backgroundColor = "#ffffff";
tb_wrapper.style.height = "30px";
tb_wrapper.style.width = "50px";
var tb_play = document.createElement('button');
tb_play.id = "toolbar_play_button";
tb_play.title = "Play";
tb_play.innerHTML = "►";
tb_play.style.height = "100%";
tb_play.style.width = "100%";
tb_play.style.lineHeight = "12px";
tb_play.addEventListener("click", function() {
playButtonOnClickEventListener();
});
tb_wrapper.appendChild(tb_play);
dom_body.appendChild(tb_wrapper);
}
function playButtonOnClickEventListener() {
//Now we can use the window selection object
var window_selection = window.getSelection();
console.log(window_selection);
//Also, Word Online adds special class name to every selected element
//in the document. So, this is another way to get the selected text.
var elements_selection = document.getElementsByClassName("Selected");
console.log(elements_selection);
}
И вот скриншот доказательства:
Есть результаты доступа к выделенному тексту в документе Word Online
Я не уверен, как построен редактор Word Online или почему вы не можете использовать window.getSelection()
, но одна вещь, которую я сразу заметил, заключается в том, что при выделении текста в нем, редактор дает этот текст Selected
учебный класс. Так, может быть, вы могли бы как-то воспользоваться этим? Переопределить стиль соответствующих элементов?
Возможно, вы могли бы использовать MutationObserver
и ищите это имя класса, добавляемое к элементам. Вам нужно будет поэкспериментировать, чтобы убедиться, что это работает для ваших нужд, и, очевидно, если Microsoft изменит имя класса или поведение, ваше расширение сломается.
Попробуйте выбрать текст и поставить
document.getElementsByClassName("Selected")[0].innerHTML
в консоли.