mirror of
https://github.com/ankitects/anki.git
synced 2025-09-19 14:32:22 -04:00
separate basic and extended paste modes
- basic mode is the default, and includes only HTML elements that can be added/edited easily with the default editor - extended mode is enabled by holding down shift and includes a bunch of other HTML elements
This commit is contained in:
parent
23e0034278
commit
1d3e5787a2
3 changed files with 43 additions and 20 deletions
|
@ -646,8 +646,13 @@ to a cloze type first, via Edit>Change Note Type."""))
|
||||||
def doPaste(self, html, internal):
|
def doPaste(self, html, internal):
|
||||||
if not internal:
|
if not internal:
|
||||||
html = self._pastePreFilter(html)
|
html = self._pastePreFilter(html)
|
||||||
self.web.eval("pasteHTML(%s, %s);" % (
|
extended = self.mw.app.queryKeyboardModifiers() & Qt.ShiftModifier
|
||||||
json.dumps(html), json.dumps(internal)))
|
if extended:
|
||||||
|
extended = "true"
|
||||||
|
else:
|
||||||
|
extended = "false"
|
||||||
|
self.web.eval("pasteHTML(%s, %s, %s);" % (
|
||||||
|
json.dumps(html), json.dumps(internal), extended))
|
||||||
|
|
||||||
def doDrop(self, html, internal):
|
def doDrop(self, html, internal):
|
||||||
self.web.evalWithCallback("makeDropTargetCurrent();",
|
self.web.evalWithCallback("makeDropTargetCurrent();",
|
||||||
|
|
|
@ -99,6 +99,8 @@ class AnkiWebView(QWebEngineView):
|
||||||
QShortcut(key, self,
|
QShortcut(key, self,
|
||||||
context=Qt.WidgetWithChildrenShortcut,
|
context=Qt.WidgetWithChildrenShortcut,
|
||||||
activated=fn)
|
activated=fn)
|
||||||
|
QShortcut(QKeySequence("ctrl+shift+v"), self,
|
||||||
|
context=Qt.WidgetWithChildrenShortcut, activated=self.onPaste)
|
||||||
|
|
||||||
self.focusProxy().installEventFilter(self)
|
self.focusProxy().installEventFilter(self)
|
||||||
|
|
||||||
|
|
|
@ -300,18 +300,18 @@ function hideDupes() {
|
||||||
$("#dupes").hide();
|
$("#dupes").hide();
|
||||||
}
|
}
|
||||||
|
|
||||||
var pasteHTML = function (html, internal) {
|
var pasteHTML = function (html, internal, allowedTags) {
|
||||||
html = filterHTML(html, internal);
|
html = filterHTML(html, internal, allowedTags);
|
||||||
setFormat("inserthtml", html);
|
setFormat("inserthtml", html);
|
||||||
};
|
};
|
||||||
|
|
||||||
var filterHTML = function (html, internal) {
|
var filterHTML = function (html, internal, extendedMode) {
|
||||||
// wrap it in <top> as we aren't allowed to change top level elements
|
// wrap it in <top> as we aren't allowed to change top level elements
|
||||||
var top = $.parseHTML("<ankitop>" + html + "</ankitop>")[0];
|
var top = $.parseHTML("<ankitop>" + html + "</ankitop>")[0];
|
||||||
if (internal) {
|
if (internal) {
|
||||||
filterInternalNode(top);
|
filterInternalNode(top);
|
||||||
} else {
|
} else {
|
||||||
filterNode(top);
|
filterNode(top, extendedMode);
|
||||||
}
|
}
|
||||||
var outHtml = top.innerHTML;
|
var outHtml = top.innerHTML;
|
||||||
//console.log(`input html: ${html}`);
|
//console.log(`input html: ${html}`);
|
||||||
|
@ -319,20 +319,31 @@ var filterHTML = function (html, internal) {
|
||||||
return outHtml;
|
return outHtml;
|
||||||
};
|
};
|
||||||
|
|
||||||
var allowedTags = {};
|
var allowedTagsBasic = {};
|
||||||
|
var allowedTagsExtended = {};
|
||||||
|
|
||||||
var TAGS_WITHOUT_ATTRS = ["H1", "H2", "H3", "P", "DIV", "BR", "LI", "UL",
|
var TAGS_WITHOUT_ATTRS = ["P", "DIV", "BR",
|
||||||
"OL", "B", "I", "U", "BLOCKQUOTE", "CODE", "EM",
|
"B", "I", "U", "EM", "STRONG", "SUB", "SUP"];
|
||||||
"STRONG", "PRE", "SUB", "SUP", "TABLE", "DD", "DT", "DL"];
|
var i;
|
||||||
for (var i = 0; i < TAGS_WITHOUT_ATTRS.length; i++) {
|
for (i = 0; i < TAGS_WITHOUT_ATTRS.length; i++) {
|
||||||
allowedTags[TAGS_WITHOUT_ATTRS[i]] = {"attrs": []};
|
allowedTagsBasic[TAGS_WITHOUT_ATTRS[i]] = {"attrs": []};
|
||||||
}
|
}
|
||||||
|
|
||||||
allowedTags["A"] = {"attrs": ["HREF"]};
|
TAGS_WITHOUT_ATTRS = ["H1", "H2", "H3", "LI", "UL", "BLOCKQUOTE", "CODE",
|
||||||
allowedTags["TR"] = {"attrs": ["ROWSPAN"]};
|
"PRE", "TABLE", "DD", "DT", "DL"];
|
||||||
allowedTags["TD"] = {"attrs": ["COLSPAN", "ROWSPAN"]};
|
for (i = 0; i < TAGS_WITHOUT_ATTRS.length; i++) {
|
||||||
allowedTags["TH"] = {"attrs": ["COLSPAN", "ROWSPAN"]};
|
allowedTagsExtended[TAGS_WITHOUT_ATTRS[i]] = {"attrs": []};
|
||||||
allowedTags["IMG"] = {"attrs": ["SRC"]};
|
}
|
||||||
|
|
||||||
|
allowedTagsBasic["IMG"] = {"attrs": ["SRC"]};
|
||||||
|
|
||||||
|
allowedTagsExtended["A"] = {"attrs": ["HREF"]};
|
||||||
|
allowedTagsExtended["TR"] = {"attrs": ["ROWSPAN"]};
|
||||||
|
allowedTagsExtended["TD"] = {"attrs": ["COLSPAN", "ROWSPAN"]};
|
||||||
|
allowedTagsExtended["TH"] = {"attrs": ["COLSPAN", "ROWSPAN"]};
|
||||||
|
|
||||||
|
// add basic tags to extended
|
||||||
|
Object.assign(allowedTagsExtended, allowedTagsBasic);
|
||||||
|
|
||||||
// filtering from another field
|
// filtering from another field
|
||||||
var filterInternalNode = function (node) {
|
var filterInternalNode = function (node) {
|
||||||
|
@ -348,7 +359,7 @@ var filterInternalNode = function (node) {
|
||||||
};
|
};
|
||||||
|
|
||||||
// filtering from external sources
|
// filtering from external sources
|
||||||
var filterNode = function (node) {
|
var filterNode = function (node, extendedMode) {
|
||||||
// text node?
|
// text node?
|
||||||
if (node.nodeType === 3) {
|
if (node.nodeType === 3) {
|
||||||
return;
|
return;
|
||||||
|
@ -363,14 +374,19 @@ var filterNode = function (node) {
|
||||||
nodes.push(node.childNodes[i]);
|
nodes.push(node.childNodes[i]);
|
||||||
}
|
}
|
||||||
for (i = 0; i < nodes.length; i++) {
|
for (i = 0; i < nodes.length; i++) {
|
||||||
filterNode(nodes[i]);
|
filterNode(nodes[i], extendedMode);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (node.tagName === "ANKITOP") {
|
if (node.tagName === "ANKITOP") {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var tag = allowedTags[node.tagName];
|
var tag;
|
||||||
|
if (extendedMode) {
|
||||||
|
tag = allowedTagsExtended[node.tagName];
|
||||||
|
} else {
|
||||||
|
tag = allowedTagsBasic[node.tagName];
|
||||||
|
}
|
||||||
if (!tag) {
|
if (!tag) {
|
||||||
if (!node.innerHTML) {
|
if (!node.innerHTML) {
|
||||||
node.parentNode.removeChild(node);
|
node.parentNode.removeChild(node);
|
||||||
|
|
Loading…
Reference in a new issue