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

📄 khtml_caret.cpp

📁 konqueror3 embedded版本, KDE环境下的当家浏览器的嵌入式版本源码包.
💻 CPP
📖 第 1 页 / 共 5 页
字号:
/* This file is part of the KDE project * * Copyright (C) 2003-2004 Leo Savernik <l.savernik@aon.at> * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; see the file COPYING.LIB.  If not, write to * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */#include "khtml_caret_p.h"#include "html/html_documentimpl.h"namespace khtml {/** Flags representing the type of advance that has been made. * @param LeftObject a render object was left and an ascent to its parent has *	taken place * @param AdvancedToSibling an actual advance to a sibling has taken place * @param EnteredObject a render object was entered by descending into it from *	its parent object. */enum ObjectAdvanceState {  LeftObject = 0x01, AdvancedToSibling = 0x02, EnteredObject = 0x04};/** All possible states that may occur during render object traversal. * @param OutsideDescending outside of the current object, ready to descend *	into children * @param InsideDescending inside the current object, descending into *	children * @param InsideAscending inside the current object, ascending to parents * @param OutsideAscending outsie the current object, ascending to parents */enum ObjectTraversalState {  OutsideDescending, InsideDescending, InsideAscending, OutsideAscending};/** Traverses the render object tree in a fine granularity. * @param obj render object * @param trav object traversal state * @param toBegin traverse towards beginning * @param base base render object which this method must not advance beyond *	(0 means document) * @param state object advance state (enum ObjectAdvanceState) * @return the render object according to the state. May be the same as \c obj */static RenderObject* traverseRenderObjects(RenderObject *obj,		ObjectTraversalState &trav, bool toBegin, RenderObject *base,                int &state){  RenderObject *r;  switch (trav) {    case OutsideDescending:      trav = InsideDescending;      break;    case InsideDescending:      r = toBegin ? obj->lastChild() : obj->firstChild();      if (r) {        trav = OutsideDescending;        obj = r;        state |= EnteredObject;      } else {        trav = InsideAscending;      }      break;    case InsideAscending:      trav = OutsideAscending;      break;    case OutsideAscending:      r = toBegin ? obj->previousSibling() : obj->nextSibling();      if (r) {        trav = OutsideDescending;        state |= AdvancedToSibling;      } else {        r = obj->parent();        if (r == base) r = 0;        trav = InsideAscending;        state |= LeftObject;      }      obj = r;      break;  }/*end switch*/  return obj;}/** Like RenderObject::objectBelow, but confined to stay within \c base. * @param obj render object to begin with * @param trav object traversal state, will be reset within this function * @param base base render object (0: no base) */static inline RenderObject *renderObjectBelow(RenderObject *obj, ObjectTraversalState &trav, RenderObject *base){  trav = InsideDescending;  int state;		// we don't need the state, so we don't initialize it  RenderObject *r = obj;  while (r && trav != OutsideDescending) {    r = traverseRenderObjects(r, trav, false, base, state);#if DEBUG_CARETMODE > 3    kdDebug(6200) << "renderObjectBelow: r " << r << " trav " << trav << endl;#endif  }  trav = InsideDescending;  return r;}/** Like RenderObject::objectAbove, but confined to stay within \c base. * @param obj render object to begin with * @param trav object traversal state, will be reset within this function * @param base base render object (0: no base) */static inline RenderObject *renderObjectAbove(RenderObject *obj, ObjectTraversalState &trav, RenderObject *base){  trav = OutsideAscending;  int state;		// we don't need the state, so we don't initialize it  RenderObject *r = obj;  while (r && trav != InsideAscending) {    r = traverseRenderObjects(r, trav, true, base, state);#if DEBUG_CARETMODE > 3    kdDebug(6200) << "renderObjectAbove: r " << r << " trav " << trav << endl;#endif  }  trav = InsideAscending;  return r;}/** Checks whether the given inline box matches the IndicatedFlows policy * @param box inline box to test * @return true on match */static inline bool isIndicatedInlineBox(InlineBox *box){  // text boxes are never indicated.  if (box->isInlineTextBox()) return false;  RenderStyle *s = box->object()->style();  return s->borderLeftWidth() || s->borderRightWidth()  	|| s->borderTopWidth() || s->borderBottomWidth()	|| s->paddingLeft().value() || s->paddingRight().value()	|| s->paddingTop().value() || 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.	|| s->marginLeft().value() || s->marginRight().value();}/** Checks whether the given render object matches the IndicatedFlows policy * @param r render object to test * @return true on match */static inline bool isIndicatedFlow(RenderObject *r){  RenderStyle *s = r->style();  return s->borderLeftStyle() != BNONE || s->borderRightStyle() != BNONE  	|| s->borderTopStyle() != BNONE || s->borderBottomStyle() != BNONE//	|| s->paddingLeft().value() || s->paddingRight().value()//	|| s->paddingTop().value() || s->paddingBottom().value()//	|| s->marginLeft().value() || s->marginRight().value()	|| s->hasClip() || s->overflow() != OVISIBLE	|| s->backgroundColor().isValid() || s->backgroundImage();}/** Advances to the next render object, taking into account the current * traversal state. * * @param r render object * @param trav object traversal state * @param toBegin @p true, advance towards beginning, @p false, advance toward end * @param base base render object which this method must not advance beyond *	(0 means document) * @param state object advance state (enum ObjectAdvanceState) (unchanged *	on LeafsOnly) * @return a pointer to the render object which we advanced to, *	or 0 if the last possible object has been reached. */static RenderObject *advanceObject(RenderObject *r,		ObjectTraversalState &trav, bool toBegin,                RenderObject *base, int &state){  ObjectTraversalState origtrav = trav;  RenderObject *a = traverseRenderObjects(r, trav, toBegin, base, state);  bool ignoreOutsideDesc = toBegin && origtrav == OutsideAscending;  // render object and traversal state at which look ahead has been started  RenderObject *la = 0;  ObjectTraversalState latrav = trav;  ObjectTraversalState lasttrav = origtrav;  while (a) {#if DEBUG_CARETMODE > 5kdDebug(6200) << "a " << a << " trav " << trav << endl;#endif    if (a->element()) {#if DEBUG_CARETMODE > 4kdDebug(6200) << "a " << a << " trav " << trav << " origtrav " << origtrav << " ignoreOD " << ignoreOutsideDesc << endl;#endif      if (toBegin) {        switch (origtrav) {	  case OutsideDescending:            if (trav == InsideAscending) return a;	    if (trav == OutsideDescending) return a;	    break;          case InsideDescending:	    if (trav == OutsideDescending) return a;	    // fall through          case InsideAscending:            if (trav == OutsideAscending) return a;	    break;	  case OutsideAscending:	    if (trav == OutsideAscending) return a;            if (trav == InsideAscending && lasttrav == InsideDescending) return a;	    if (trav == OutsideDescending && !ignoreOutsideDesc) return a;	    // ignore this outside descending position, as it effectively	    // demarkates the same position, but remember it in case we fall off	    // the document.	    la = a; latrav = trav;	    ignoreOutsideDesc = false;	    break;        }/*end switch*/      } else {        switch (origtrav) {	  case OutsideDescending:            if (trav == InsideAscending) return a;	    if (trav == OutsideDescending) return a;	    break;          case InsideDescending://	    if (trav == OutsideDescending) return a;	    // fall through          case InsideAscending://            if (trav == OutsideAscending) return a;//	    break;	  case OutsideAscending:	    // ### what if origtrav == OA, and immediately afterwards trav	    // becomes OD? In this case the effective position hasn't changed ->	    // the caret gets stuck. Otherwise, it apparently cannot happen in	    // real usage patterns.	    if (trav == OutsideDescending) return a;	    if (trav == OutsideAscending) {	      if (la) return la;              // starting lookahead here. Remember old object in case we fall off	      // the document.	      la = a; latrav = trav;	    }	    break;	}/*end switch*/      }/*end if*/    }/*end if*/    lasttrav = trav;    a = traverseRenderObjects(a, trav, toBegin, base, state);  }/*wend*/  if (la) trav = latrav, a = la;  return a;}/** Check whether the current render object is unsuitable in caret mode handling. * * Some render objects cannot be handled correctly in caret mode. These objects * are therefore considered to be unsuitable. The null object is suitable, as * it denotes reaching the end. * @param r current render object * @param trav current traversal state */static inline bool isUnsuitable(RenderObject *r, ObjectTraversalState trav){  if (!r) return false;  return r->isTableCol() || r->isTableSection() || r->isTableRow()  	|| (r->isText() && static_cast<RenderText *>(r)->inlineTextBoxCount() == 0);      ;  Q_UNUSED(trav);}/** Advances to the next render object, taking into account the current * traversal state, but skipping render objects which are not suitable for * having placed the caret into them. * @param r render object * @param trav object traversal state (unchanged on LeafsOnly) * @param toBegin @p true, advance towards beginning, @p false, advance toward end * @param base base render object which this method must not advance beyond *	(0 means document) * @param state object advance state (enum ObjectAdvanceState) (unchanged *	on LeafsOnly) * @return a pointer to the advanced render object or 0 if the last possible *	object has been reached. */static inline RenderObject *advanceSuitableObject(RenderObject *r,		ObjectTraversalState &trav, bool toBegin,		RenderObject *base, int &state){  do {    r = advanceObject(r, trav, toBegin, base, state);#if DEBUG_CARETMODE > 2    kdDebug(6200) << "after advanceSWP: r " << r << " trav " << trav << " toBegin " << toBegin << endl;#endif  } while (isUnsuitable(r, trav));  return r;}/**  * Returns the next leaf node.  *  * Using this function delivers leaf nodes as if the whole DOM tree  * were a linear chain of its leaf nodes.  * @param r dom node  * @param baseElem base element not to search beyond  * @return next leaf node or 0 if there are no more.  */static NodeImpl *nextLeafNode(NodeImpl *r, NodeImpl *baseElem){  NodeImpl *n = r->firstChild();  if (n) {    while (n) { r = n; n = n->firstChild(); }    return const_cast<NodeImpl *>(r);  }/*end if*/  n = r->nextSibling();  if (n) {    r = n;    while (n) { r = n; n = n->firstChild(); }    return const_cast<NodeImpl *>(r);  }/*end if*/  n = r->parentNode();  if (n == baseElem) n = 0;  while (n) {    r = n;    n = r->nextSibling();    if (n) {      r = n;      n = r->firstChild();      while (n) { r = n; n = n->firstChild(); }      return const_cast<NodeImpl *>(r);    }/*end if*/    n = r->parentNode();    if (n == baseElem) n = 0;  }/*wend*/  return 0;}#if 0		// currently not used/** (Not part of the official DOM)  * Returns the previous leaf node.  *  * Using this function delivers leaf nodes as if the whole DOM tree  * were a linear chain of its leaf nodes.  * @param r dom node  * @param baseElem base element not to search beyond  * @return previous leaf node or 0 if there are no more.  */static NodeImpl *prevLeafNode(NodeImpl *r, NodeImpl *baseElem){  NodeImpl *n = r->firstChild();  if (n) {

⌨️ 快捷键说明

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