⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 khtml_caret.cpp

📁 konqueror3 embedded版本, KDE环境下的当家浏览器的嵌入式版本源码包.
💻 CPP
📖 第 1 页 / 共 5 页
字号:
  InlineFlowBox *flowBox = cbl->baseFlowBox();  if (flowBox) {    flowBox = static_cast<InlineFlowBox *>(toBegin ? flowBox->prevLineBox() : flowBox->nextLineBox());    if (flowBox) {      bool seekOutside = false, seekOutsideEnd = false; // silence gcc uninit warning      CaretBoxIterator it;      cbl = CaretBoxLine::constructCaretBoxLine(&lines->cblDeleter,          flowBox, flowBox->firstChild(), seekOutside, seekOutsideEnd, it);    }/*end if*/  }/*end if*/  // if there are no more lines in this block, move towards block to come  if (!flowBox) { if (toBegin) prevBlock(); else nextBlock(); }#if DEBUG_CARETMODE > 3  if (cbl) kdDebug(6200) << cbl->information() << endl;#endif}// == class EditableCaretBoxIterator implementationvoid EditableCaretBoxIterator::advance(bool toBegin){#if DEBUG_CARETMODE > 3      kdDebug(6200) << "---------------" << k_funcinfo << "toBegin " << toBegin << endl;#endif  const CaretBoxIterator preBegin = cbl->preBegin();  const CaretBoxIterator end = cbl->end();  CaretBoxIterator lastbox = *this, curbox;  bool islastuseable = true;	// silence gcc  bool iscuruseable;  // Assume adjacency of caret boxes. Will be falsified later if applicable.  adjacent = true;#if DEBUG_CARETMODE > 4//       kdDebug(6200) << "ebit::advance: before: " << (**this)->object() << "@" << (**this)->object()->renderName() << ".node " << (**this)->object()->element() << "[" << ((**this)->object()->element() ? (**this)->object()->element()->nodeName().string() : QString::null) << "] inline " << (**this)->isInline() << " outside " << (**this)->isOutside() << " outsideEnd " << (**this)->isOutsideEnd() << endl;#endif  if (toBegin) CaretBoxIterator::operator --(); else CaretBoxIterator::operator ++();  bool curAtEnd = *this == preBegin || *this == end;  curbox = *this;  bool atEnd = true;  if (!curAtEnd) {    iscuruseable = isEditable(curbox, toBegin);    if (toBegin) CaretBoxIterator::operator --(); else CaretBoxIterator::operator ++();    atEnd = *this == preBegin || *this == end;  }  while (!curAtEnd) {    bool haslast = lastbox != end && lastbox != preBegin;    bool hascoming = !atEnd;    bool iscominguseable = true; // silence gcc    if (!atEnd) iscominguseable = isEditable(*this, toBegin);    if (iscuruseable) {#if DEBUG_CARETMODE > 3      kdDebug(6200) << "ebit::advance: " << (*curbox)->object() << "@" << (*curbox)->object()->renderName() << ".node " << (*curbox)->object()->element() << "[" << ((*curbox)->object()->element() ? (*curbox)->object()->element()->nodeName().string() : QString::null) << "] inline " << (*curbox)->isInline() << " outside " << (*curbox)->isOutside() << " outsideEnd " << (*curbox)->isOutsideEnd() << endl;#endif      CaretBox *box = *curbox;      if (box->isOutside()) {        // if this caret box represents no inline box, it is an outside box	// which has to be considered unconditionally        if (!box->isInline()) break;        if (advpol == VisibleFlows) break;	// IndicatedFlows and LeafsOnly are treated equally in caret box lines	InlineBox *ibox = box->inlineBox();	// get previous inline box	InlineBox *prev = box->isOutsideEnd() ? ibox : ibox->prevOnLine();	// get next inline box	InlineBox *next = box->isOutsideEnd() ? ibox->nextOnLine() : ibox;	const bool isprevindicated = !prev || isIndicatedInlineBox(prev);	const bool isnextindicated = !next || isIndicatedInlineBox(next);	const bool last = haslast && !islastuseable;	const bool coming = hascoming && !iscominguseable;	const bool left = !prev || prev->isInlineFlowBox() && isprevindicated		|| (toBegin && coming || !toBegin && last);	const bool right = !next || next->isInlineFlowBox() && isnextindicated		|| (!toBegin && coming || toBegin && last);        const bool text2indicated = toBegin && next && next->isInlineTextBox()                && isprevindicated            || !toBegin && prev && prev->isInlineTextBox() && isnextindicated;        const bool indicated2text = !toBegin && next && next->isInlineTextBox()                && prev && isprevindicated            // ### this code is so broken.            /*|| toBegin && prev && prev->isInlineTextBox() && isnextindicated*/;#if DEBUG_CARETMODE > 5      kdDebug(6200) << "prev " << prev << " haslast " << haslast << " islastuseable " << islastuseable << " left " << left << " next " << next << " hascoming " << hascoming << " iscominguseable " << iscominguseable << " right " << right << " text2indicated " << text2indicated << " indicated2text " << indicated2text << endl;#endif	if (left && right && !text2indicated || indicated2text) {	  adjacent = false;#if DEBUG_CARETMODE > 4      kdDebug(6200) << "left && right && !text2indicated || indicated2text" << endl;#endif	  break;	}      } else {        // inside boxes are *always* valid#if DEBUG_CARETMODE > 4if (box->isInline()) {        InlineBox *ibox = box->inlineBox();      kdDebug(6200) << "inside " << (!ibox->isInlineFlowBox() || static_cast<InlineFlowBox *>(ibox)->firstChild() ? "non-empty" : "empty") << (isIndicatedInlineBox(ibox) ? " indicated" : "") << " adjacent=" << adjacent << endl;    }#if 0  RenderStyle *s = ibox->object()->style();  kdDebug(6200)	<< "bordls " << s->borderLeftStyle()  		<< " bordl " << (s->borderLeftStyle() != BNONE)  		<< " bordr " << (s->borderRightStyle() != BNONE)  		<< " bordt " << (s->borderTopStyle() != BNONE)      		<< " bordb " << (s->borderBottomStyle() != BNONE)		<< " padl " << s->paddingLeft().value()                << " padr " << s->paddingRight().value()      		<< " padt " << s->paddingTop().value()                << " padb " << s->paddingBottom().value()	// ### Can inline elements have top/bottom margins? Couldn't find	// it in the CSS 2 spec, but Mozilla ignores them, so we do, too.		<< " marl " << s->marginLeft().value()                << " marr " << s->marginRight().value()      		<< endl;#endif#endif        break;      }/*end if*/    } else {      if (!(*curbox)->isOutside()) {        // cannot be adjacent anymore	adjacent = false;      }    }/*end if*/    lastbox = curbox;    islastuseable = iscuruseable;    curbox = *this;    iscuruseable = iscominguseable;    curAtEnd = atEnd;    if (!atEnd) {      if (toBegin) CaretBoxIterator::operator --(); else CaretBoxIterator::operator ++();      atEnd = *this == preBegin || *this == end;    }/*end if*/  }/*wend*/  *static_cast<CaretBoxIterator *>(this) = curbox;#if DEBUG_CARETMODE > 4//  kdDebug(6200) << "still valid? " << (*this != preBegin && *this != end) << endl;#endif#if DEBUG_CARETMODE > 3      kdDebug(6200) << "---------------" << k_funcinfo << "end " << endl;#endif}bool EditableCaretBoxIterator::isEditable(const CaretBoxIterator &boxit, bool fromEnd){  Q_ASSERT(boxit != cbl->end() && boxit != cbl->preBegin());  CaretBox *b = *boxit;  RenderObject *r = b->object();#if DEBUG_CARETMODE > 0//  if (b->isInlineFlowBox()) kdDebug(6200) << "b is inline flow box" << (outside ? " (outside)" : "") << endl;  kdDebug(6200) << "isEditable r" << r << ": " << (r ? r->renderName() : QString::null) << (r && r->isText() ? " contains \"" + QString(((RenderText *)r)->str->s, QMIN(((RenderText *)r)->str->l,15)) + "\"" : QString::null) << endl;#endif  // Must check caret mode or design mode *after* r->element(), otherwise  // lines without a backing DOM node get regarded, leading to a crash.  // ### check should actually be in InlineBoxIterator  NodeImpl *node = r->element();  ObjectTraversalState trav;  mapRenderPosToTraversalState(b->isOutside(), b->isOutsideEnd(), fromEnd, trav);  if (isUnsuitable(r, trav) || !node) {    return false;  }  // generally exclude replaced elements with no children from navigation  if (!b->isOutside() && r->isRenderReplaced() && !r->firstChild())    return false;  RenderObject *eff_r = r;  bool globallyNavigable = m_part->isCaretMode() || m_part->isEditable();  // calculate the parent element's editability if this inline box is outside.  if (b->isOutside() && !globallyNavigable) {    NodeImpl *par = node->parent();    // I wonder whether par can be 0. It shouldn't be possible if the    // algorithm contained no bugs.    Q_ASSERT(par);    if (par) node = par;    eff_r = node->renderer();    Q_ASSERT(eff_r);	// this is a hard requirement  }  bool result = globallyNavigable || eff_r->style()->userInput() == UI_ENABLED;#if DEBUG_CARETMODE > 0  kdDebug(6200) << result << endl;#endif  return result;}// == class EditableLineIterator implementationvoid EditableLineIterator::advance(bool toBegin){  CaretAdvancePolicy advpol = lines->advancePolicy();  LineIterator lasteditable, lastindicated;  bool haslasteditable = false;  bool haslastindicated = false;  bool uselasteditable = false;  LineIterator::advance(toBegin);  while (cbl) {    if (isEditable(*this)) {#if DEBUG_CARETMODE > 3      kdDebug(6200) << "advance: " << cbl->enclosingObject() << "@" << cbl->enclosingObject()->renderName() << ".node " << cbl->enclosingObject()->element() << "[" << (cbl->enclosingObject()->element() ? cbl->enclosingObject()->element()->nodeName().string() : QString::null) << "]" << endl;#endif      bool hasindicated = isIndicatedFlow(cbl->enclosingObject());      if (hasindicated) {        haslastindicated = true;        lastindicated = *this;      }      switch (advpol) {        case IndicatedFlows:          if (hasindicated) goto wend;          // fall through        case LeafsOnly:          if (cbl->isOutside()) break;          // fall through        case VisibleFlows: goto wend;      }/*end switch*/      // remember rejected editable element      lasteditable = *this;      haslasteditable = true;#if DEBUG_CARETMODE > 4      kdDebug(6200) << "remembered lasteditable " << *lasteditable << endl;#endif    } else {      // If this element isn't editable, but the last one was, and it was only      // rejected because it didn't match the caret advance policy, force it.      // Otherwise certain combinations of editable and uneditable elements      // could never be reached with some policies.      if (haslasteditable) { uselasteditable = true; break; }    }    LineIterator::advance(toBegin);  }/*wend*/wend:  if (uselasteditable) *this = haslastindicated ? lastindicated : lasteditable;  if (!cbl && haslastindicated) *this = lastindicated;}// == class EditableCharacterIterator implementationvoid EditableCharacterIterator::initFirstChar(){  CaretBox *box = *ebit;  InlineBox *b = box->inlineBox();  if (_offset == box->maxOffset())    peekNext();  else if (b && !box->isOutside() && b->isInlineTextBox())    _char = static_cast<RenderText *>(b->object())->str->s[_offset].unicode();  else    _char = -1;}/** returns true when the given caret box is empty, i. e. should not * take place in caret movement. */static inline bool isCaretBoxEmpty(CaretBox *box) {  if (!box->isInline()) return false;  InlineBox *ibox = box->inlineBox();  return ibox->isInlineFlowBox()  		&& !static_cast<InlineFlowBox *>(ibox)->firstChild()      		&& !isIndicatedInlineBox(ibox);}EditableCharacterIterator &EditableCharacterIterator::operator ++(){  _offset++;  CaretBox *box = *ebit;  InlineBox *b = box->inlineBox();  long maxofs = box->maxOffset();#if DEBUG_CARETMODE > 0  kdDebug(6200) << "box->maxOffset() " << box->maxOffset() << " box->minOffset() " << box->minOffset() << endl;#endif  if (_offset == maxofs) {#if DEBUG_CARETMODE > 2kdDebug(6200) << "_offset == maxofs: " << _offset << " == " << maxofs << endl;#endif    peekNext();  } else if (_offset > maxofs) {#if DEBUG_CARETMODE > 2kdDebug(6200) << "_offset > maxofs: " << _offset << " > " << maxofs /*<< " _peekNext: " << _peekNext*/ << endl;#endif    if (/*!_peekNext*/true) {      ++ebit;      if (ebit == (*_it)->end()) {	// end of line reached, go to next line        ++_it;#if DEBUG_CARETMODE > 3kdDebug(6200) << "++_it" << endl;#endif        if (_it != _it.lines->end()) {	  ebit = _it;          box = *ebit;          b = box->inlineBox();#if DEBUG_CARETMODE > 3kdDebug(6200) << "box " << box << " b " << b << " isText " << box->isInlineTextBox() << endl;#endif#if DEBUG_CARETMODE > 3	  RenderObject *_r = box->object();kdDebug(6200) << "_r " << _r << ":" << _r->element()->nodeName().string() << endl;#endif	  _offset = box->minOffset();#if DEBUG_CARETMODE > 3kdDebug(6200) << "_offset " << _offset << endl;#endif	} else {          b = 0;	  _end = true;	}/*end if*/        goto readchar;      }/*end if*/    }/*end if*/    bool adjacent = ebit.isAdjacent();#if 0    // Jump over element if this one is not a text node.    if (adjacent && !(*ebit)->isInlineTextBox()) {      EditableCaretBoxIterator copy = ebit;      ++ebit;      if (ebit != (*_it)->end() && (*ebit)->isInlineTextBox()          /*&& (!(*ebit)->isInlineFlowBox()              || static_cast<InlineFlowBox *>(*ebit)->)*/)        adjacent = false;      else ebit = copy;    }/*end if*/#endif    // Jump over empty elements.    if (adjacent && !(*ebit)->isInlineTextBox()) {      bool noemptybox = true;      while (isCaretBoxEmpty(*ebit)) {        noemptybox = false;        EditableCaretBoxIterator copy = ebit;        ++ebit;        if (ebit == (*_it)->end()) { ebit = copy; break; }      }      if (noemptybox) adjacent = false;    }/*end if*///     _r = (*ebit)->object();    /*if (!_it.outside) */_offset = (*ebit)->minOffset() + adjacent;    //_peekNext = 0;    box = *ebit;    b = box->inlineBox();    goto readchar;  } else {readchar:    // get character    if (b && !box->isOutside() && b->isInlineTextBox() && _offset < b->maxOffset())      _char = 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -