📄 preloadscanner.cpp
字号:
m_state = BeforeAttributeName; break; } if (cc >= 'A' && cc <= 'Z') m_tagName.append(cc + 0x20); else m_tagName.append(cc); m_source.advance(); if (m_source.isEmpty()) return; cc = *m_source; } break; case BeforeAttributeName: if (isWhitespace(cc)) ; else if (cc == '>') { emitTag(); m_state = Data; } else if (cc >= 'A' && cc <= 'Z') { m_attributeName.clear(); m_attributeValue.clear(); m_attributeName.append(cc + 0x20); m_state = AttributeName; } else if (cc == '/') ; else { m_attributeName.clear(); m_attributeValue.clear(); m_attributeName.append(cc); m_state = AttributeName; } break; case AttributeName: while (1) { if (isWhitespace(cc)) { m_state = AfterAttributeName; break; } if (cc == '=') { m_state = BeforeAttributeValue; break; } if (cc == '>') { emitTag(); m_state = Data; break; } if (cc == '/') { m_state = BeforeAttributeName; break; } if (cc >= 'A' && cc <= 'Z') m_attributeName.append(cc + 0x20); else m_attributeName.append(cc); m_source.advance(); if (m_source.isEmpty()) return; cc = *m_source; } break; case AfterAttributeName: if (isWhitespace(cc)) ; else if (cc == '=') m_state = BeforeAttributeValue; else if (cc == '>') { emitTag(); m_state = Data; } else if (cc >= 'A' && cc <= 'Z') { m_attributeName.clear(); m_attributeValue.clear(); m_attributeName.append(cc + 0x20); m_state = AttributeName; } else if (cc == '/') m_state = BeforeAttributeName; else { m_attributeName.clear(); m_attributeValue.clear(); m_attributeName.append(cc); m_state = AttributeName; } break; case BeforeAttributeValue: if (isWhitespace(cc)) ; else if (cc == '"') m_state = AttributeValueDoubleQuoted; else if (cc == '&') { m_state = AttributeValueUnquoted; continue; } else if (cc == '\'') m_state = AttributeValueSingleQuoted; else if (cc == '>') { emitTag(); m_state = Data; } else { m_attributeValue.append(cc); m_state = AttributeValueUnquoted; } break; case AttributeValueDoubleQuoted: while (1) { if (cc == '"') { processAttribute(); m_state = BeforeAttributeName; break; } if (cc == '&') { m_stateBeforeEntityInAttributeValue = m_state; m_state = EntityInAttributeValue; break; } m_attributeValue.append(cc); m_source.advance(); if (m_source.isEmpty()) return; cc = *m_source; } break; case AttributeValueSingleQuoted: while (1) { if (cc == '\'') { processAttribute(); m_state = BeforeAttributeName; break; } if (cc == '&') { m_stateBeforeEntityInAttributeValue = m_state; m_state = EntityInAttributeValue; break; } m_attributeValue.append(cc); m_source.advance(); if (m_source.isEmpty()) return; cc = *m_source; } break; case AttributeValueUnquoted: while (1) { if (isWhitespace(cc)) { processAttribute(); m_state = BeforeAttributeName; break; } if (cc == '&') { m_stateBeforeEntityInAttributeValue = m_state; m_state = EntityInAttributeValue; break; } if (cc == '>') { processAttribute(); emitTag(); m_state = Data; break; } m_attributeValue.append(cc); m_source.advance(); if (m_source.isEmpty()) return; cc = *m_source; } break; case EntityInAttributeValue: { bool notEnoughCharacters = false; unsigned entity = consumeEntity(m_source, notEnoughCharacters); if (notEnoughCharacters) return; if (entity > 0xFFFF) { m_attributeValue.append(U16_LEAD(entity)); m_attributeValue.append(U16_TRAIL(entity)); } else if (entity) m_attributeValue.append(entity); else m_attributeValue.append('&'); } m_state = m_stateBeforeEntityInAttributeValue; continue; case BogusComment: while (1) { if (cc == '>') { m_state = Data; break; } m_source.advance(); if (m_source.isEmpty()) return; cc = *m_source; } break; case MarkupDeclarationOpen: { if (cc == '-') { if (m_source.length() < 2) return; m_source.advance(); cc = *m_source; if (cc == '-') m_state = CommentStart; else { m_state = BogusComment; continue; } // If we cared about the DOCTYPE we would test to enter those states here } else { m_state = BogusComment; continue; } break; } case CommentStart: if (cc == '-') m_state = CommentStartDash; else if (cc == '>') m_state = Data; else m_state = Comment; break; case CommentStartDash: if (cc == '-') m_state = CommentEnd; else if (cc == '>') m_state = Data; else m_state = Comment; break; case Comment: while (1) { if (cc == '-') { m_state = CommentEndDash; break; } m_source.advance(); if (m_source.isEmpty()) return; cc = *m_source; } break; case CommentEndDash: if (cc == '-') m_state = CommentEnd; else m_state = Comment; break; case CommentEnd: if (cc == '>') m_state = Data; else if (cc == '-') ; else m_state = Comment; break; } m_source.advance(); }} void PreloadScanner::processAttribute(){ AtomicString tag = AtomicString(m_tagName.data(), m_tagName.size()); AtomicString attribute = AtomicString(m_attributeName.data(), m_attributeName.size()); String value(m_attributeValue.data(), m_attributeValue.size()); if (tag == scriptTag || tag == imgTag) { if (attribute == srcAttr && m_urlToLoad.isEmpty()) m_urlToLoad = parseURL(value); else if (attribute == charsetAttr) m_charset = value; } else if (tag == linkTag) { if (attribute == hrefAttr && m_urlToLoad.isEmpty()) m_urlToLoad = parseURL(value); else if (attribute == relAttr) { bool styleSheet = false; bool alternate = false; bool icon = false; bool dnsPrefetch = false; HTMLLinkElement::tokenizeRelAttribute(value, styleSheet, alternate, icon, dnsPrefetch); m_linkIsStyleSheet = styleSheet && !alternate && !icon && !dnsPrefetch; } else if (attribute == charsetAttr) m_charset = value; }} inline void PreloadScanner::emitCharacter(UChar c){ if (m_contentModel == CDATA && m_lastStartTag == styleTag) tokenizeCSS(c);} inline void PreloadScanner::tokenizeCSS(UChar c){ // We are just interested in @import rules, no need for real tokenization here // Searching for other types of resources is probably low payoff switch (m_cssState) { case CSSInitial: if (c == '@') m_cssState = CSSRuleStart; else if (c == '/') m_cssState = CSSMaybeComment; break; case CSSMaybeComment: if (c == '*') m_cssState = CSSComment; else m_cssState = CSSInitial; break; case CSSComment: if (c == '*') m_cssState = CSSMaybeCommentEnd; break; case CSSMaybeCommentEnd: if (c == '/') m_cssState = CSSInitial; else if (c == '*') ; else m_cssState = CSSComment; break; case CSSRuleStart: if ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z')) { m_cssRule.clear(); m_cssRuleValue.clear(); m_cssRule.append(c); m_cssState = CSSRule; } else m_cssState = CSSInitial; break; case CSSRule: if (isWhitespace(c)) m_cssState = CSSAfterRule; else if (c == ';') m_cssState = CSSInitial; else m_cssRule.append(c); break; case CSSAfterRule: if (isWhitespace(c)) ; else if (c == ';') m_cssState = CSSInitial; else { m_cssState = CSSRuleValue; m_cssRuleValue.append(c); } break; case CSSRuleValue: if (isWhitespace(c)) m_cssState = CSSAfterRuleValue; else if (c == ';') { emitCSSRule(); m_cssState = CSSInitial; } else m_cssRuleValue.append(c); break; case CSSAfterRuleValue: if (isWhitespace(c)) ; else if (c == ';') { emitCSSRule(); m_cssState = CSSInitial; } else { // FIXME media rules m_cssState = CSSInitial; } break; }} void PreloadScanner::emitTag(){ if (m_closeTag) { m_contentModel = PCDATA; m_cssState = CSSInitial; clearLastCharacters(); return; } AtomicString tag(m_tagName.data(), m_tagName.size()); m_lastStartTag = tag; if (tag == textareaTag || tag == titleTag) m_contentModel = RCDATA; else if (tag == styleTag || tag == xmpTag || tag == scriptTag || tag == iframeTag || tag == noembedTag || tag == noframesTag) m_contentModel = CDATA; else if (tag == noscriptTag) // we wouldn't be here if scripts were disabled m_contentModel = CDATA; else if (tag == plaintextTag) m_contentModel = PLAINTEXT; else m_contentModel = PCDATA; if (tag == bodyTag) m_bodySeen = true; if (m_urlToLoad.isEmpty()) { m_linkIsStyleSheet = false; return; } if (tag == scriptTag) m_document->docLoader()->preload(CachedResource::Script, m_urlToLoad, m_charset, scanningBody()); else if (tag == imgTag) m_document->docLoader()->preload(CachedResource::ImageResource, m_urlToLoad, String(), scanningBody()); else if (tag == linkTag && m_linkIsStyleSheet) m_document->docLoader()->preload(CachedResource::CSSStyleSheet, m_urlToLoad, m_charset, scanningBody()); m_urlToLoad = String(); m_charset = String(); m_linkIsStyleSheet = false;} void PreloadScanner::emitCSSRule(){ String rule(m_cssRule.data(), m_cssRule.size()); if (equalIgnoringCase(rule, "import") && !m_cssRuleValue.isEmpty()) { String value(m_cssRuleValue.data(), m_cssRuleValue.size()); String url = parseURL(value); if (!url.isEmpty()) m_document->docLoader()->preload(CachedResource::CSSStyleSheet, url, String(), scanningBody()); } m_cssRule.clear(); m_cssRuleValue.clear();} }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -