mirror of
https://github.com/ONLYOFFICE/onlyoffice.github.io.git
synced 2026-02-10 18:05:06 +08:00
Refactoring spell&gramma windows
This commit is contained in:
@ -36,268 +36,17 @@
|
||||
<link rel="stylesheet" href="https://onlyoffice.github.io/sdkjs-plugins/v1/plugins.css">
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Grammar Suggestion</title>
|
||||
<style>
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
|
||||
background: white;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
color:rgb(61,61,61)
|
||||
}
|
||||
|
||||
.popup {
|
||||
background: white;
|
||||
border-radius: 4px;
|
||||
box-shadow: 0 2px 16px rgba(0, 0, 0, 0.2);
|
||||
border: 1px solid #d0d0d0;
|
||||
overflow: hidden;
|
||||
max-width: 320px;
|
||||
min-width: 280px;
|
||||
}
|
||||
|
||||
.popup-header {
|
||||
background: rgb(241,241,241);
|
||||
color: #333;
|
||||
padding: 10px 12px;
|
||||
font-size: 12px;
|
||||
font-weight: bold;
|
||||
display: flex;
|
||||
text-align: center;
|
||||
letter-spacing: 0.01em;
|
||||
align-items: center;
|
||||
border-bottom: 1px solid #d0d0d0;
|
||||
position: relative;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.close-icon {
|
||||
cursor: pointer;
|
||||
color: #666;
|
||||
font-size: 18px;
|
||||
line-height: 1;
|
||||
padding: 2px 4px;
|
||||
transition: color 0.2s;
|
||||
position: absolute;
|
||||
right: 8px;
|
||||
}
|
||||
|
||||
.close-icon:hover {
|
||||
color: #000;
|
||||
}
|
||||
|
||||
.popup-body {
|
||||
padding: 16px 16px 0 16px;
|
||||
}
|
||||
|
||||
.section {
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
.section:last-of-type {
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.label {
|
||||
font-size: 11px;
|
||||
font-weight: 700;
|
||||
color: #333;
|
||||
margin-bottom: 6px;
|
||||
}
|
||||
|
||||
.correction {
|
||||
font-size: 12px;
|
||||
color: #000;
|
||||
line-height: 1.5;
|
||||
background: #f5f5f5;
|
||||
border: 1px solid #d0d0d0;
|
||||
border-radius: 3px;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.correction-text {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.original {
|
||||
color: #000;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
.arrow {
|
||||
color: #666;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.suggested {
|
||||
color: #000;
|
||||
font-weight: normal;
|
||||
}
|
||||
.suggested strong {
|
||||
color: #F62211;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.explanation {
|
||||
font-size: 12px;
|
||||
color: #000;
|
||||
line-height: 1.5;
|
||||
background: #f5f5f5;
|
||||
border: 1px solid #d0d0d0;
|
||||
border-radius: 3px;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.button-container {
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
padding: 16px;
|
||||
border-top: 1px solid #d0d0d0;
|
||||
margin: 0 -16px;
|
||||
}
|
||||
|
||||
.btn {
|
||||
flex: 1;
|
||||
padding: 0px 0px;
|
||||
border: 1px solid #d0d0d0;
|
||||
border-radius: 2px;
|
||||
font-size: 11px;
|
||||
letter-spacing: 0.01em;
|
||||
line-height: var(--line-height-base, 1.5);
|
||||
font-weight: bold;
|
||||
vertical-align: middle;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s;
|
||||
font-family: inherit;
|
||||
background: white;
|
||||
color: #333;
|
||||
display: inline-block;
|
||||
width: 86px;
|
||||
height: 22px;
|
||||
}
|
||||
|
||||
.btn-accept {
|
||||
background: #2c2c2c;
|
||||
color: white;
|
||||
border-color: #2c2c2c;
|
||||
}
|
||||
|
||||
.btn-accept:hover {
|
||||
background: #1a1a1a;
|
||||
border-color: #1a1a1a;
|
||||
}
|
||||
|
||||
.btn-reject {
|
||||
background: white;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.btn-reject:hover {
|
||||
background: #f5f5f5;
|
||||
}
|
||||
|
||||
.btn:active {
|
||||
transform: scale(0.98);
|
||||
}
|
||||
</style>
|
||||
<title>Annotation popup</title>
|
||||
</head>
|
||||
<body>
|
||||
<div class="popup" id="popup">
|
||||
<div class="popup-header">
|
||||
<span id="title">Grammar suggestion</span>
|
||||
<span class="close-icon" id="closeIcon">×</span>
|
||||
</div>
|
||||
<div class="popup-body">
|
||||
<div class="section">
|
||||
<div class="label">Suggested correction</div>
|
||||
<div class="correction">
|
||||
<div class="correction-text">
|
||||
<span class="original" id="original"></span>
|
||||
<span class="arrow">→</span>
|
||||
<span class="suggested" id="suggested"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="section" id="explanation-section">
|
||||
<div class="label">Explanation</div>
|
||||
<div class="explanation" id="explanation"></div>
|
||||
</div>
|
||||
|
||||
<div class="button-container">
|
||||
<button class="btn btn-accept" id="acceptBtn">Accept</button>
|
||||
<button class="btn btn-reject" id="rejectBtn">Reject</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<body style="margin:0; padding:0;">
|
||||
<script>
|
||||
let errorData = {
|
||||
"title" : "Grammar suggestion",
|
||||
"original": "",
|
||||
"suggested": "",
|
||||
"explanation": ""
|
||||
};
|
||||
|
||||
function displayError(error)
|
||||
{
|
||||
document.getElementById('title').textContent = error.title;
|
||||
document.getElementById('original').textContent = error.original;
|
||||
document.getElementById('suggested').innerHTML = error.suggested;
|
||||
|
||||
if (!error.explanation) {
|
||||
document.getElementById('explanation-section').style.display = "none";
|
||||
} else {
|
||||
document.getElementById('explanation-section').style.display = "block";
|
||||
document.getElementById('explanation').textContent = error.explanation;
|
||||
}
|
||||
|
||||
errorData = error;
|
||||
}
|
||||
|
||||
displayError(errorData);
|
||||
|
||||
window.updateError = function (newError)
|
||||
{
|
||||
displayError(newError);
|
||||
};
|
||||
|
||||
document.getElementById('acceptBtn').addEventListener('click', function ()
|
||||
{
|
||||
window.Asc.plugin.sendToPlugin("onAccept");
|
||||
});
|
||||
|
||||
document.getElementById('rejectBtn').addEventListener('click', function ()
|
||||
{
|
||||
window.Asc.plugin.sendToPlugin("onReject");
|
||||
});
|
||||
|
||||
window.Asc.plugin.init = function() {
|
||||
window.Asc.plugin.sendToPlugin("onWindowReady", {});
|
||||
window.Asc.plugin.attachEvent("onUpdateSuggestion", function(obj) {
|
||||
displayError(obj);
|
||||
window.Asc.plugin.sendToPlugin("onUpdateSize", [document.body.scrollWidth, document.body.scrollHeight]);
|
||||
window.Asc.plugin.attachEvent("onUpdateContent", function(content) {
|
||||
document.body.innerHTML = content;
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
window.Asc.plugin.attachEvent("onThemeChanged", function(){
|
||||
|
||||
});
|
||||
|
||||
document.getElementById('closeIcon').addEventListener('click', function ()
|
||||
{
|
||||
window.Asc.plugin.sendToPlugin("onClose");
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@ -691,7 +691,7 @@ window.Asc.plugin.onTranslate = async function() {
|
||||
await initWithTranslate(1);
|
||||
};
|
||||
|
||||
window.Asc.plugin.button = function(id, windowId) {
|
||||
window.Asc.plugin.button = async function(id, windowId) {
|
||||
if (!windowId) {
|
||||
return
|
||||
}
|
||||
@ -702,6 +702,22 @@ window.Asc.plugin.button = function(id, windowId) {
|
||||
delete window.chatWindow;
|
||||
}
|
||||
|
||||
if (textAnnotatorPopup && textAnnotatorPopup.popup && textAnnotatorPopup.popup.id === windowId)
|
||||
{
|
||||
switch (id) {
|
||||
case 0:
|
||||
await textAnnotatorPopup.popup.onAccept();
|
||||
break;
|
||||
case 1:
|
||||
await textAnnotatorPopup.popup.onReject();
|
||||
break;
|
||||
default:
|
||||
textAnnotatorPopup.close();
|
||||
break;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (settingsWindow && windowId === settingsWindow.id) {
|
||||
settingsWindow.close();
|
||||
settingsWindow = null;
|
||||
|
||||
@ -36,15 +36,20 @@ function TextAnnotationPopup()
|
||||
this.type = 0; // 0 - spelling, 1 - grammar
|
||||
this.paraId = -1;
|
||||
this.rangeId = -1;
|
||||
|
||||
this.content = "";
|
||||
this.width = 318;
|
||||
this.height = 500;
|
||||
|
||||
this.open = function(type, paraId, rangeId)
|
||||
this.open = function(type, paraId, rangeId, data)
|
||||
{
|
||||
if (this.popup && 0 === this.type && 1 === type)
|
||||
return null;
|
||||
|
||||
this._calculateWindowSize(data);
|
||||
return this._open(type, paraId, rangeId);
|
||||
};
|
||||
|
||||
|
||||
this._open = function(type, paraId, rangeId)
|
||||
{
|
||||
if (this.type === type
|
||||
@ -62,24 +67,21 @@ function TextAnnotationPopup()
|
||||
let variation = {
|
||||
url : 'annotationPopup.html',
|
||||
isVisual : true,
|
||||
buttons : [],
|
||||
buttons : this._getButtons(),
|
||||
isModal : false,
|
||||
isCustomWindow : true,
|
||||
description: this._getTitle(),
|
||||
EditorsSupport : ["word", "slide", "cell", "pdf"],
|
||||
size : [318, 500],
|
||||
isTargeted : true,
|
||||
transparent : true
|
||||
size : [this.width, this.height],
|
||||
fixedSize : true,
|
||||
isTargeted : true
|
||||
};
|
||||
let _t = this;
|
||||
let popup = new window.Asc.PluginWindow();
|
||||
popup.attachEvent("onClose", function() {
|
||||
_t.close();
|
||||
});
|
||||
popup.attachEvent("onUpdateSize", function(size) {
|
||||
if (size[0] !== variation.size[0] || size[1] !== variation.size[1]) {
|
||||
Asc.Editor.callMethod("ResizeWindow", [popup.id, [size[0], size[1]]]);
|
||||
}
|
||||
|
||||
let _t = this;
|
||||
popup.attachEvent("onWindowReady", function() {
|
||||
popup.command("onUpdateContent", _t.content);
|
||||
});
|
||||
|
||||
popup.show(variation);
|
||||
this.popup = popup;
|
||||
return popup;
|
||||
@ -100,7 +102,74 @@ function TextAnnotationPopup()
|
||||
this.popup.close();
|
||||
this.popup = null;
|
||||
Asc.Editor.callMethod("FocusEditor");
|
||||
}
|
||||
};
|
||||
|
||||
this._getTitle = function()
|
||||
{
|
||||
return window.Asc.plugin.tr(this.type === 0 ? "Spelling suggestion" : "Grammar suggestion");
|
||||
};
|
||||
|
||||
this._getButtons = function()
|
||||
{
|
||||
return [
|
||||
{ text: window.Asc.plugin.tr('Accept'), primary: true },
|
||||
{ text: window.Asc.plugin.tr('Reject'), primary: false }
|
||||
];
|
||||
};
|
||||
|
||||
this._calculateWindowSize = function(data)
|
||||
{
|
||||
let backColor = window.Asc.plugin.theme ? window.Asc.plugin.theme["background-normal"] : "#FFFFFF";
|
||||
let textColor = window.Asc.plugin.theme ? window.Asc.plugin.theme["text-normal"] : "#3D3D3D";
|
||||
let borderColor = window.Asc.plugin.theme ? window.Asc.plugin.theme["border-divider"] : "#666666";
|
||||
let ballonColor = window.Asc.plugin.theme ? window.Asc.plugin.theme["canvas-background"] : "#F5F5F5";
|
||||
this.content = `<div style="background:${backColor}; overflow:hidden; max-width:320px; min-width:280px;color:${textColor}; user-select:none;font-family:-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;">
|
||||
<div style="padding:16px 16px 0px 16px;">
|
||||
|
||||
<div style="margin-bottom:12px;">
|
||||
<div style="font-size:11px; font-weight:700; color:${textColor}; margin-bottom:6px;">
|
||||
${window.Asc.plugin.tr("Suggested correction")}
|
||||
</div>
|
||||
|
||||
<div style="font-size:12px; color:${textColor}; line-height:1.5; background:${ballonColor}; border:1px solid ${borderColor}; border-radius:3px; padding:10px;">
|
||||
<div style="display:flex; align-items:center; gap:8px;">
|
||||
<span style="color:${textColor}; font-weight:normal;">${data.original}</span>
|
||||
<span style="color:${borderColor}; font-weight:bold;">→</span>
|
||||
<span style="color:${textColor}; font-weight:normal;">${data.suggested}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>`;
|
||||
|
||||
if (data.explanation) {
|
||||
this.content += `<div style="margin-bottom:16px;">
|
||||
<div style="font-size:11px; font-weight:700; color:${textColor}; margin-bottom:6px;">
|
||||
${window.Asc.plugin.tr("Explanation")}
|
||||
</div>
|
||||
|
||||
<div style="font-size:12px; color:${textColor}; line-height:1.5; background:${ballonColor}; border:1px solid ${borderColor}; border-radius:3px; padding:10px;">${data.explanation}</div>
|
||||
</div>`;
|
||||
}
|
||||
|
||||
this.content += "</div></div>";
|
||||
|
||||
let measureDiv = document.createElement("div");
|
||||
measureDiv.style.position = "absolute";
|
||||
measureDiv.style.left = "-9999px";
|
||||
measureDiv.style.top = "-9999px";
|
||||
measureDiv.style.width = this.width + "px";
|
||||
measureDiv.style.visibility = "hidden";
|
||||
measureDiv.style.pointerEvents = "none";
|
||||
measureDiv.style.opacity = "0";
|
||||
measureDiv.style.margin = "0";
|
||||
measureDiv.style.padding = "0";
|
||||
measureDiv.innerHTML = this.content;
|
||||
|
||||
document.body.appendChild(measureDiv);
|
||||
|
||||
this.height = measureDiv.scrollHeight;
|
||||
|
||||
document.body.removeChild(measureDiv);
|
||||
};
|
||||
}
|
||||
|
||||
var textAnnotatorPopup = new TextAnnotationPopup();
|
||||
|
||||
@ -219,10 +219,9 @@ GrammarChecker.prototype.getInfoForPopup = function(paraId, rangeId)
|
||||
{
|
||||
let _s = this.getAnnotation(paraId, rangeId);
|
||||
return {
|
||||
"title" : "Grammar suggestion",
|
||||
"suggested" : _s["difference"],
|
||||
"original" : _s["original"],
|
||||
"explanation" : _s["description"]
|
||||
suggested : _s["difference"],
|
||||
original : _s["original"],
|
||||
explanation : _s["description"]
|
||||
};
|
||||
};
|
||||
GrammarChecker.prototype.onAccept = async function(paraId, rangeId)
|
||||
|
||||
@ -210,9 +210,8 @@ SpellChecker.prototype.getInfoForPopup = function(paraId, rangeId)
|
||||
{
|
||||
let anot = this.getAnnotation(paraId, rangeId);
|
||||
return {
|
||||
"title" : "Spelling suggestion",
|
||||
"suggested" : anot["suggested"],
|
||||
"original" : anot["original"]
|
||||
suggested : anot["suggested"],
|
||||
original : anot["original"]
|
||||
};
|
||||
};
|
||||
SpellChecker.prototype.onAccept = async function(paraId, rangeId)
|
||||
|
||||
@ -91,22 +91,19 @@ TextAnnotator.prototype.openPopup = async function(paraId, rangeId)
|
||||
if (!textAnnotatorPopup)
|
||||
return;
|
||||
|
||||
let popup = textAnnotatorPopup.open(this.type, paraId, rangeId);
|
||||
let popup = textAnnotatorPopup.open(this.type, paraId, rangeId, this.getInfoForPopup(paraId, rangeId));
|
||||
if (!popup)
|
||||
return;
|
||||
|
||||
|
||||
let _t = this;
|
||||
popup.attachEvent("onWindowReady", function() {
|
||||
popup.command("onUpdateSuggestion", _t.getInfoForPopup(paraId, rangeId));
|
||||
});
|
||||
popup.attachEvent("onAccept", async function() {
|
||||
popup.onAccept = async function() {
|
||||
await _t.onAccept(paraId, rangeId);
|
||||
_t.closePopup();
|
||||
});
|
||||
popup.attachEvent("onReject", async function() {
|
||||
};
|
||||
popup.onReject = async function() {
|
||||
await _t.onReject(paraId, rangeId);
|
||||
_t.closePopup();
|
||||
});
|
||||
};
|
||||
};
|
||||
TextAnnotator.prototype.closePopup = function()
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user