📄 html_elementimpl.cpp
字号:
static inline bool isHexDigit( const QChar &c ) { return ( c >= '0' && c <= '9' ) || ( c >= 'a' && c <= 'f' ) || ( c >= 'A' && c <= 'F' );}static inline int toHex( const QChar &c ) { return ( (c >= '0' && c <= '9') ? (c.unicode() - '0') : ( ( c >= 'a' && c <= 'f' ) ? (c.unicode() - 'a' + 10) : ( ( c >= 'A' && c <= 'F' ) ? (c.unicode() - 'A' + 10) : -1 ) ) );}/* color parsing that tries to match as close as possible IE 6. */void HTMLElementImpl::addHTMLColor( int id, const DOMString &c ){ if(!m_styleDecls) createDecl(); // this is the only case no color gets applied in IE. if ( !c.length() ) { removeCSSProperty(id); return; } if ( m_styleDecls->setProperty(id, c, false, true) ) return; QString color = c.string(); // not something that fits the specs. // we're emulating IEs color parser here. It maps transparent to black, otherwise it tries to build a rgb value // out of everyhting you put in. The algorithm is experimentally determined, but seems to work for all test cases I have. // the length of the color value is rounded up to the next // multiple of 3. each part of the rgb triple then gets one third // of the length. // // Each triplet is parsed byte by byte, mapping // each number to a hex value (0-9a-fA-F to their values // everything else to 0). // // The highest non zero digit in all triplets is remembered, and // used as a normalization point to normalize to values between 0 // and 255. if ( color.lower() != "transparent" ) { if ( color[0] == '#' ) color.remove( 0, 1 ); int basicLength = (color.length() + 2) / 3; if ( basicLength > 1 ) { // IE ignores colors with three digits or less// qDebug("trying to fix up color '%s'. basicLength=%d, length=%d",// color.latin1(), basicLength, color.length() ); int colors[3] = { 0, 0, 0 }; int component = 0; int pos = 0; int maxDigit = basicLength-1; while ( component < 3 ) { // search forward for digits in the string int numDigits = 0; while ( pos < (int)color.length() && numDigits < basicLength ) { int hex = toHex( color[pos] ); colors[component] = (colors[component] << 4); if ( hex > 0 ) { colors[component] += hex; maxDigit = kMin( maxDigit, numDigits ); } numDigits++; pos++; } while ( numDigits++ < basicLength ) colors[component] <<= 4; component++; } maxDigit = basicLength - maxDigit;// qDebug("color is %x %x %x, maxDigit=%d", colors[0], colors[1], colors[2], maxDigit ); // normalize to 00-ff. The highest filled digit counts, minimum is 2 digits maxDigit -= 2; colors[0] >>= 4*maxDigit; colors[1] >>= 4*maxDigit; colors[2] >>= 4*maxDigit;// qDebug("normalized color is %x %x %x", colors[0], colors[1], colors[2] ); // assert( colors[0] < 0x100 && colors[1] < 0x100 && colors[2] < 0x100 ); color.sprintf("#%02x%02x%02x", colors[0], colors[1], colors[2] );// qDebug( "trying to add fixed color string '%s'", color.latin1() ); if ( m_styleDecls->setProperty(id, DOMString(color), false, true) ) return; } } m_styleDecls->setProperty(id, CSS_VAL_BLACK, false, true);}void HTMLElementImpl::removeCSSProperty(int id){ if(!m_styleDecls) return; m_styleDecls->setParent(getDocument()->elementSheet()); m_styleDecls->removeProperty(id, true /*nonCSSHint */); setChanged();}DOMString HTMLElementImpl::innerHTML() const{ DOMString result = ""; for (NodeImpl *child = firstChild(); child != NULL; child = child->nextSibling()) result += child->toString(); return result;}DOMString HTMLElementImpl::innerText() const{ DOMString text = ""; if(!firstChild()) return text; const NodeImpl *n = this; // find the next text/image after the anchor, to get a position while(n) { if(n->firstChild()) n = n->firstChild(); else if(n->nextSibling()) n = n->nextSibling(); else { NodeImpl *next = 0; while(!next) { n = n->parentNode(); if(!n || n == (NodeImpl *)this ) goto end; next = n->nextSibling(); } n = next; } if(n->isTextNode() ) { text += static_cast<const TextImpl *>(n)->data(); } } end: return text;}DocumentFragment HTMLElementImpl::createContextualFragment( const DOMString &html ){ // the following is in accordance with the definition as used by IE if( endTag[id()] == FORBIDDEN ) return DocumentFragment(); // IE disallows innerHTML on inline elements. // I don't see why we should have this restriction, as our // dhtml engine can cope with it. Lars //if ( isInline() ) return false; switch( id() ) { case ID_COL: case ID_COLGROUP: case ID_FRAMESET: case ID_HEAD: case ID_STYLE: case ID_TABLE: case ID_TBODY: case ID_TFOOT: case ID_THEAD: case ID_TITLE: return DocumentFragment(); default: break; } if ( !getDocument()->isHTMLDocument() ) return DocumentFragment(); DocumentFragmentImpl* fragment = new DocumentFragmentImpl( docPtr() ); DocumentFragment f( fragment ); { HTMLTokenizer tok( docPtr(), fragment ); tok.begin(); tok.write( html.string(), true ); tok.end(); } // Exceptions are ignored because none ought to happen here. int ignoredExceptionCode; // we need to pop <html> and <body> elements and remove <head> to // accomadate folks passing complete HTML documents to make the // child of an element. Node n; for ( NodeImpl* node = fragment->firstChild(); node; ) { if (node->id() == ID_HTML || node->id() == ID_BODY) { NodeImpl* firstChild = node->firstChild(); NodeImpl* child = firstChild; while ( child ) { NodeImpl *nextChild = child->nextSibling(); n = fragment->insertBefore(child, node, ignoredExceptionCode); child = nextChild; } if ( !firstChild ) { NodeImpl *nextNode = node->nextSibling(); n = fragment->removeChild(node, ignoredExceptionCode); node = nextNode; } else { n = fragment->removeChild(node, ignoredExceptionCode); node = firstChild; } } else if (node->id() == ID_HEAD) { NodeImpl *nextNode = node->nextSibling(); n = fragment->removeChild(node, ignoredExceptionCode); node = nextNode; } else { node = node->nextSibling(); } } return f;}void HTMLElementImpl::setInnerHTML( const DOMString &html, int &exceptioncode ){ DocumentFragment fragment = createContextualFragment( html ); if ( fragment.isNull() ) { exceptioncode = DOMException::NO_MODIFICATION_ALLOWED_ERR; return; } // Make sure adding the new child is ok, before removing all children (#96187) checkAddChild( fragment.handle(), exceptioncode ); if ( exceptioncode ) return; removeChildren(); appendChild( fragment.handle(), exceptioncode );}void HTMLElementImpl::setInnerText( const DOMString &text, int& exceptioncode ){ // following the IE specs. if( endTag[id()] == FORBIDDEN ) { exceptioncode = DOMException::NO_MODIFICATION_ALLOWED_ERR; return; } // IE disallows innerHTML on inline elements. I don't see why we should have this restriction, as our // dhtml engine can cope with it. Lars //if ( isInline() ) return false; switch( id() ) { case ID_COL: case ID_COLGROUP: case ID_FRAMESET: case ID_HEAD: case ID_HTML: case ID_TABLE: case ID_TBODY: case ID_TFOOT: case ID_THEAD: case ID_TR: exceptioncode = DOMException::NO_MODIFICATION_ALLOWED_ERR; return; default: break; } removeChildren(); TextImpl *t = new TextImpl( docPtr(), text.implementation() ); appendChild( t, exceptioncode );}void HTMLElementImpl::addHTMLAlignment( DOMString alignment ){ //qDebug("alignment is %s", alignment.string().latin1() ); // vertical alignment with respect to the current baseline of the text // right or left means floating images int propfloat = -1; int propvalign = -1; if ( strcasecmp( alignment, "absmiddle" ) == 0 ) { propvalign = CSS_VAL_MIDDLE; } else if ( strcasecmp( alignment, "absbottom" ) == 0 ) { propvalign = CSS_VAL_BOTTOM; } else if ( strcasecmp( alignment, "left" ) == 0 ) { propfloat = CSS_VAL_LEFT; propvalign = CSS_VAL_TOP; } else if ( strcasecmp( alignment, "right" ) == 0 ) { propfloat = CSS_VAL_RIGHT; propvalign = CSS_VAL_TOP; } else if ( strcasecmp( alignment, "top" ) == 0 ) { propvalign = CSS_VAL_TOP; } else if ( strcasecmp( alignment, "middle" ) == 0 ) { propvalign = CSS_VAL__KHTML_BASELINE_MIDDLE; } else if ( strcasecmp( alignment, "center" ) == 0 ) { propvalign = CSS_VAL_MIDDLE; } else if ( strcasecmp( alignment, "bottom" ) == 0 ) { propvalign = CSS_VAL_BASELINE; } else if ( strcasecmp ( alignment, "texttop") == 0 ) { propvalign = CSS_VAL_TEXT_TOP; } if ( propfloat != -1 ) addCSSProperty( CSS_PROP_FLOAT, propfloat ); if ( propvalign != -1 ) addCSSProperty( CSS_PROP_VERTICAL_ALIGN, propvalign );}DOMString HTMLElementImpl::toString() const{ if (!hasChildNodes()) { DOMString result = openTagStartToString(); result += ">"; if (endTag[id()] == REQUIRED) { result += "</"; result += tagName(); result += ">"; } return result; } return ElementImpl::toString();}// -------------------------------------------------------------------------HTMLGenericElementImpl::HTMLGenericElementImpl(DocumentPtr *doc, ushort i) : HTMLElementImpl(doc){ _id = i;}HTMLGenericElementImpl::~HTMLGenericElementImpl(){}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -