📄 dom_selection.cpp
字号:
if (pos.inRenderedContent()) return true; // not currently rendered, try moving to prev Position prev = pos.previousCharacterPosition(); if (prev != pos && prev.node()->inSameContainingBlockFlowElement(pos.node())) { moveTo(prev); return true; } // could not be moved to prev, try next Position next = pos.nextCharacterPosition(); if (next != pos && next.node()->inSameContainingBlockFlowElement(pos.node())) { moveTo(next); return true; } return false;}bool Selection::nodeIsBeforeNode(NodeImpl *n1, NodeImpl *n2) const{ if (!n1 || !n2) return true; if (n1 == n2) return true; bool result = false; int n1Depth = 0; int n2Depth = 0; // First we find the depths of the two nodes in the tree (n1Depth, n2Depth) NodeImpl *n = n1; while (n->parentNode()) { n = n->parentNode(); n1Depth++; } n = n2; while (n->parentNode()) { n = n->parentNode(); n2Depth++; } // Climb up the tree with the deeper node, until both nodes have equal depth while (n2Depth > n1Depth) { n2 = n2->parentNode(); n2Depth--; } while (n1Depth > n2Depth) { n1 = n1->parentNode(); n1Depth--; } // Climb the tree with both n1 and n2 until they have the same parent while (n1->parentNode() != n2->parentNode()) { n1 = n1->parentNode(); n2 = n2->parentNode(); } // Iterate through the parent's children until n1 or n2 is found n = n1->parentNode() ? n1->parentNode()->firstChild() : n1->firstChild(); while (n) { if (n == n1) { result = true; break; } else if (n == n2) { result = false; break; } n = n->nextSibling(); } return result;}static bool firstRunAt(RenderObject *renderNode, int y, NodeImpl *&startNode, long &startOffset){ for (RenderObject *n = renderNode; n; n = n->nextSibling()) { if (n->isText()) { RenderText *textRenderer = static_cast<khtml::RenderText *>(n); for (InlineTextBox* box = textRenderer->firstTextBox(); box; box = box->nextTextBox()) { if (box->m_y == y) { startNode = textRenderer->element(); startOffset = box->m_start; return true; } } } if (firstRunAt(n->firstChild(), y, startNode, startOffset)) { return true; } } return false;}static bool lastRunAt(RenderObject *renderNode, int y, NodeImpl *&endNode, long &endOffset){ RenderObject *n = renderNode; if (!n) { return false; } RenderObject *next; while ((next = n->nextSibling())) { n = next; } while (1) { if (lastRunAt(n->firstChild(), y, endNode, endOffset)) { return true; } if (n->isText()) { RenderText *textRenderer = static_cast<khtml::RenderText *>(n); for (InlineTextBox* box = textRenderer->lastTextBox(); box; box = box->prevTextBox()) { if (box->m_y == y) { endNode = textRenderer->element(); endOffset = box->m_start + box->m_len; return true; } } } if (n == renderNode) { return false; } n = n->previousSibling(); }}static bool startAndEndLineNodesIncludingNode(NodeImpl *node, int offset, Selection &selection){ if (node && (node->nodeType() == Node::TEXT_NODE || node->nodeType() == Node::CDATA_SECTION_NODE)) { int pos; int selectionPointY; RenderText *renderer = static_cast<RenderText *>(node->renderer()); InlineTextBox * run = renderer->findNextInlineTextBox( offset, pos ); DOMString t = node->nodeValue(); if (!run) return false; selectionPointY = run->m_y; // Go up to first non-inline element. khtml::RenderObject *renderNode = renderer; while (renderNode && renderNode->isInline()) renderNode = renderNode->parent(); renderNode = renderNode->firstChild(); NodeImpl *startNode = 0; NodeImpl *endNode = 0; long startOffset; long endOffset; // Look for all the first child in the block that is on the same line // as the selection point. if (!firstRunAt (renderNode, selectionPointY, startNode, startOffset)) return false; // Look for all the last child in the block that is on the same line // as the selection point. if (!lastRunAt (renderNode, selectionPointY, endNode, endOffset)) return false; selection.moveTo(Position(startNode, startOffset), Position(endNode, endOffset)); return true; } return false;}void Selection::debugRenderer(RenderObject *r, bool selected) const{ if (r->node()->isElementNode()) { ElementImpl *element = static_cast<ElementImpl *>(r->node()); fprintf(stderr, "%s%s\n", selected ? "==> " : " ", element->tagName().string().latin1()); } else if (r->isText()) { RenderText *textRenderer = static_cast<RenderText *>(r); if (textRenderer->stringLength() == 0 || !textRenderer->firstTextBox()) { fprintf(stderr, "%s#text (empty)\n", selected ? "==> " : " "); return; } static const int max = 36; QString text = DOMString(textRenderer->string()).string(); int textLength = text.length(); if (selected) { int offset = 0; if (r->node() == start().node()) offset = start().offset(); else if (r->node() == end().node()) offset = end().offset(); int pos; InlineTextBox *box = textRenderer->findNextInlineTextBox(offset, pos); text = text.mid(box->m_start, box->m_len); QString show; int mid = max / 2; int caret = 0; // text is shorter than max if (textLength < max) { show = text; caret = pos; } // too few characters to left else if (pos - mid < 0) { show = text.left(max - 3) + "..."; caret = pos; } // enough characters on each side else if (pos - mid >= 0 && pos + mid <= textLength) { show = "..." + text.mid(pos - mid + 3, max - 6) + "..."; caret = mid; } // too few characters on right else { show = "..." + text.right(max - 3); caret = pos - (textLength - show.length()); } show = show.replace("\n", " "); show = show.replace("\r", " "); fprintf(stderr, "==> #text : \"%s\" at offset %d\n", show.latin1(), pos); fprintf(stderr, " "); for (int i = 0; i < caret; i++) fprintf(stderr, " "); fprintf(stderr, "^\n"); } else { if ((int)text.length() > max) text = text.left(max - 3) + "..."; else text = text.left(max); fprintf(stderr, " #text : \"%s\"\n", text.latin1()); } }}void Selection::debugPosition() const{ if (!start().node()) return; //static int context = 5; //RenderObject *r = 0; fprintf(stderr, "Selection =================\n"); if (start() == end()) { Position pos = start(); Position upstream = pos.equivalentUpstreamPosition(); Position downstream = pos.equivalentDownstreamPosition(); fprintf(stderr, "upstream: %s %p:%d\n", getTagName(upstream.node()->id()).string().latin1(), upstream.node(), (int) upstream.offset()); fprintf(stderr, "pos: %s %p:%d\n", getTagName(pos.node()->id()).string().latin1(), pos.node(), (int) pos.offset()); fprintf(stderr, "downstream: %s %p:%d\n", getTagName(downstream.node()->id()).string().latin1(), downstream.node(), (int) downstream.offset()); } else { Position pos = start(); Position upstream = pos.equivalentUpstreamPosition(); Position downstream = pos.equivalentDownstreamPosition(); fprintf(stderr, "upstream: %s %p:%d\n", getTagName(upstream.node()->id()).string().latin1(), upstream.node(), (int) upstream.offset()); fprintf(stderr, "start: %s %p:%d\n", getTagName(pos.node()->id()).string().latin1(), pos.node(), (int) pos.offset()); fprintf(stderr, "downstream: %s %p:%d\n", getTagName(downstream.node()->id()).string().latin1(), downstream.node(), (int) downstream.offset()); fprintf(stderr, "-----------------------------------\n"); pos = end(); upstream = pos.equivalentUpstreamPosition(); downstream = pos.equivalentDownstreamPosition(); fprintf(stderr, "upstream: %s %p:%d\n", getTagName(upstream.node()->id()).string().latin1(), upstream.node(), (int) upstream.offset()); fprintf(stderr, "end: %s %p:%d\n", getTagName(pos.node()->id()).string().latin1(), pos.node(), (int) pos.offset()); fprintf(stderr, "downstream: %s %p:%d\n", getTagName(downstream.node()->id()).string().latin1(), downstream.node(), (int) downstream.offset()); fprintf(stderr, "-----------------------------------\n"); } #if 0 int back = 0; r = start().node()->renderer(); for (int i = 0; i < context; i++, back++) { if (r->previousRenderer()) r = r->previousRenderer(); else break; } for (int i = 0; i < back; i++) { debugRenderer(r, false); r = r->nextRenderer(); } fprintf(stderr, "\n"); if (start().node() == end().node()) debugRenderer(start().node()->renderer(), true); else for (r = start().node()->renderer(); r && r != end().node()->renderer(); r = r->nextRenderer()) debugRenderer(r, true); fprintf(stderr, "\n"); r = end().node()->renderer(); for (int i = 0; i < context; i++) { if (r->nextRenderer()) { r = r->nextRenderer(); debugRenderer(r, false); } else break; }#endif fprintf(stderr, "================================\n");}} // namespace DOM
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -