private static void AssertNextToken(CssScanner lex, CssTokenType type, Func<CssToken, bool> condition) { var token = new CssToken(); Assert.IsTrue(lex.Next(token, true), "Unexpected EOF"); Assert.AreEqual(type, token.mType); Assert.IsTrue(condition(token), "Condition for token {0} failed".Fmt(token.mType)); }
internal ErrorReporter(CssScanner aScanner, CssStyleSheet aSheet, CssLoader aLoader, Uri aUri) { mScanner = aScanner; mSheet = aSheet; mLoader = aLoader; mUri = aUri; }
public IEnumerable<string> GetUris(string aInput) { var lexer = new CssScanner(aInput, 1); lexer.SetErrorReporter(new ErrorReporter(lexer, null, this, null)); var token = new CssToken(); while (lexer.Next(token, true)) if (token.mType == CssTokenType.URL) yield return token.mIdentStr; }
public void ParseSimple() { var lex = new CssScanner("h1 { color: #123; }", 0); AssertNextToken(lex, CssTokenType.Ident, t => t.mIdent.ToString() == "h1"); AssertNextToken(lex, CssTokenType.Symbol, t => t.mSymbol == '{'); AssertNextToken(lex, CssTokenType.Ident, t => t.mIdent.ToString() == "color"); AssertNextToken(lex, CssTokenType.Symbol, t => t.mSymbol == ':'); AssertNextToken(lex, CssTokenType.Hash, t => t.mIdent.ToString() == "123"); AssertNextToken(lex, CssTokenType.Symbol, t => t.mSymbol == ';'); AssertNextToken(lex, CssTokenType.Symbol, t => t.mSymbol == '}'); AssertNextTokenEnd(lex); }
public IEnumerable <string> GetUris(string aInput) { var lexer = new CssScanner(aInput, 1); lexer.SetErrorReporter(new ErrorReporter(lexer, null, this, null)); var token = new CssToken(); while (lexer.Next(token, true)) { if (token.mType == CssTokenType.URL) { yield return(token.mIdentStr); } } }
private static void AssertNextTokenEnd(CssScanner lex) { var token = new CssToken(); Assert.IsFalse(lex.Next(token, true), "Expected EOF"); }
internal nsresult ParseRule(string aRule, Uri aSheetURI, Uri aBaseURI, nsIPrincipal aSheetPrincipal, ref Rule aResult) { if (aSheetPrincipal == null) throw new ArgumentException("Must have principal here!"); if (aBaseURI == null) throw new ArgumentException("need base URI"); aResult = null; var scanner = new nsCSSScanner(aRule, 0); var reporter = new ErrorReporter(scanner, mSheet, mChildLoader, aSheetURI); InitScanner(scanner, reporter, aSheetURI, aBaseURI, aSheetPrincipal); mSection = nsCSSSection.Charset; // callers are responsible for rejecting invalid rules. nsCSSToken tk = mToken; // Get first non-whitespace token nsresult rv = nsresult.OK; if (!GetToken(true)) { { if (!mSuppressErrors) mReporter.ReportUnexpected("PEParseRuleWSOnly"); }; mReporter.OutputError(); rv = nsresult.ERROR_DOM_SYNTAX_ERR; } else { if (nsCSSTokenType.AtKeyword == tk.mType) { // FIXME: perhaps aInsideBlock should be true when we are? Rule result = null; ParseAtRule((rule, _) => result = rule, aResult, false); aResult = result; } else { UngetToken(); Rule result = null; ParseRuleSet((rule, _) => result = rule, aResult); aResult = result; } if (aResult != null && GetToken(true)) { // garbage after rule { if (!mSuppressErrors) mReporter.ReportUnexpected("PERuleTrailing", mToken); }; aResult = null; } if (aResult == null) { rv = nsresult.ERROR_DOM_SYNTAX_ERR; mReporter.OutputError(); } } ReleaseScanner(); return rv; }
internal bool EvaluateSupportsCondition(string aDeclaration, Uri aDocURL, Uri aBaseURL, nsIPrincipal aDocPrincipal) { var scanner = new nsCSSScanner(aDeclaration, 0); var reporter = new ErrorReporter(scanner, mSheet, mChildLoader, aDocURL); InitScanner(scanner, reporter, aDocURL, aBaseURL, aDocPrincipal); using (/*var suppressErrors = */new nsAutoSuppressErrors(this)) { bool conditionMet = false; bool parsedOK = ParseSupportsCondition(ref conditionMet) && !GetToken(true); mReporter.ClearError(); ReleaseScanner(); return parsedOK && conditionMet; } }
internal nsresult ParseDeclarations(string aBuffer, Uri aSheetURI, Uri aBaseURI, nsIPrincipal aSheetPrincipal, Declaration aDeclaration, ref bool aChanged) { aChanged = false; if (aSheetPrincipal == null) throw new ArgumentException("Must have principal here!"); var scanner = new nsCSSScanner(aBuffer, 0); var reporter = new ErrorReporter(scanner, mSheet, mChildLoader, aSheetURI); InitScanner(scanner, reporter, aSheetURI, aBaseURI, aSheetPrincipal); mSection = nsCSSSection.General; mData.AssertInitialState(); aDeclaration.ClearData(); // We could check if it was already empty, but... aChanged = true; for (;;) { // If we cleared the old decl, then we want to be calling // ValueAppended as we parse. if (!ParseDeclaration(aDeclaration, nsParseDeclaration.AllowImportant, true, ref aChanged)) { if (!SkipDeclaration(false)) { break; } } } aDeclaration.CompressFrom(mData); ReleaseScanner(); return nsresult.OK; }
internal bool EvaluateSupportsDeclaration(string aProperty, string aValue, Uri aDocURL, Uri aBaseURL, nsIPrincipal aDocPrincipal) { nsCSSProperty propID = nsCSSProps.LookupProperty(aProperty, nsCSSProps.EnabledState.Enabled); if (propID == nsCSSProperty.Unknown) { return false; } var scanner = new nsCSSScanner(aValue, 0); var reporter = new ErrorReporter(scanner, mSheet, mChildLoader, aDocURL); InitScanner(scanner, reporter, aDocURL, aBaseURL, aDocPrincipal); using (/*var suppressErrors = */new nsAutoSuppressErrors(this)) { bool parsedOK = ParseProperty(propID) && !GetToken(true); mReporter.ClearError(); ReleaseScanner(); mTempData.ClearProperty(propID); mTempData.AssertInitialState(); return parsedOK; } }
public void Create() { // ReSharper disable once UnusedVariable var lex = new CssScanner("", 0); }
internal nsresult ParseSheet(string aInput, Uri aSheetURI, Uri aBaseURI, nsIPrincipal aSheetPrincipal, uint32_t aLineNumber, bool aAllowUnsafeRules) { if (aSheetPrincipal == null) throw new ArgumentException("Must have principal here!"); if (aBaseURI == null) throw new ArgumentException("need base URI"); if (aSheetURI == null) throw new ArgumentException("need sheet URI"); if (mSheet == null) throw new ArgumentException("Must have sheet to parse into"); if (mSheet == null) return nsresult.ERROR_UNEXPECTED; #if DEBUG Uri uri = mSheet.GetSheetURI(); bool equal; Debug.Assert(aSheetURI.Equals(uri, out equal).Succeeded() && equal, "Sheet URI does not match passed URI"); Debug.Assert(mSheet.Principal().Equals(aSheetPrincipal, out equal).Succeeded() && equal, "Sheet principal does not match passed principal"); #endif var scanner = new nsCSSScanner(aInput, aLineNumber); var reporter = new ErrorReporter(scanner, mSheet, mChildLoader, aSheetURI); InitScanner(scanner, reporter, aSheetURI, aBaseURI, aSheetPrincipal); int32_t ruleCount = mSheet.StyleRuleCount(); if (0 < ruleCount) { Rule lastRule = null; mSheet.GetStyleRuleAt(ruleCount - 1, ref lastRule); if (lastRule != null) { switch (lastRule.GetKind()) { case CssRuleKind.Charset: case CssRuleKind.Import: mSection = nsCSSSection.Import; break; case CssRuleKind.Namespace: mSection = nsCSSSection.NameSpace; break; default: mSection = nsCSSSection.General; break; } lastRule = null; } } else { mSection = nsCSSSection.Charset; // sheet is empty, any rules are fair } mUnsafeRulesEnabled = aAllowUnsafeRules; nsCSSToken tk = mToken; for (;;) { // Get next non-whitespace token if (!GetToken(true)) { mReporter.OutputError(); break; } if (nsCSSTokenType.HTMLComment == tk.mType) { continue; // legal here only } if (nsCSSTokenType.AtKeyword == tk.mType) { ParseAtRule((rule, _) => AppendRule(rule), this, false); continue; } UngetToken(); if (ParseRuleSet((rule, _) => AppendRule(rule), this)) { mSection = nsCSSSection.General; } } ReleaseScanner(); mUnsafeRulesEnabled = false; // XXX check for low level errors return nsresult.OK; }
internal nsresult ParseStyleAttribute(string aAttributeValue, Uri aDocURI, Uri aBaseURI, nsIPrincipal aNodePrincipal, ref StyleRule aResult) { if (aNodePrincipal == null) throw new ArgumentException("Must have principal here!"); if (aBaseURI == null) throw new ArgumentException("need base URI"); // XXX line number? var scanner = new nsCSSScanner(aAttributeValue, 0); var reporter = new ErrorReporter(scanner, mSheet, mChildLoader, aDocURI); InitScanner(scanner, reporter, aDocURI, aBaseURI, aNodePrincipal); mSection = nsCSSSection.General; // In quirks mode, allow style declarations to have braces or not // (bug 99554). bool haveBraces; if (mNavQuirkMode && GetToken(true)) { haveBraces = nsCSSTokenType.Symbol == mToken.mType && '{' == mToken.mSymbol; UngetToken(); } else { haveBraces = false; } nsParseDeclaration parseFlags = nsParseDeclaration.AllowImportant; if (haveBraces) { parseFlags |= nsParseDeclaration.InBraces; } Declaration declaration = ParseDeclarationBlock(parseFlags); if (declaration != null) { // Create a style rule for the declaration aResult = new StyleRule(null, declaration); } else { aResult = null; } ReleaseScanner(); // XXX check for low level errors return nsresult.OK; }
internal bool ParseColorString(string aBuffer, Uri aURI, // for error reporting uint32_t aLineNumber, // for error reporting ref nsCSSValue aValue) { var scanner = new nsCSSScanner(aBuffer, aLineNumber); var reporter = new ErrorReporter(scanner, mSheet, mChildLoader, aURI); InitScanner(scanner, reporter, aURI, aURI, null); // Parse a color, and check that there's nothing else after it. bool colorParsed = ParseColor(ref aValue) && !GetToken(true); mReporter.OutputError(); ReleaseScanner(); return colorParsed; }
internal nsresult ParseSelectorString(string aSelectorString, Uri aURI, // for error reporting uint32_t aLineNumber, // for error reporting ref nsCSSSelectorList aSelectorList) { var scanner = new nsCSSScanner(aSelectorString, aLineNumber); var reporter = new ErrorReporter(scanner, mSheet, mChildLoader, aURI); InitScanner(scanner, reporter, aURI, aURI, null); bool success = ParseSelectorList(ref aSelectorList, '\0'); // We deliberately do not call OUTPUT_ERROR here, because all our // callers map a failure return to a JS exception, and if that JS // exception is caught, people don't want to see parser diagnostics; // see e.g. http://bugs.jquery.com/ticket/7535 // It would be nice to be able to save the parser diagnostics into // the exception, so that if it _isn't_ caught we can report them // along with the usual uncaught-exception message, but we don't // have any way to do that at present; see bug 631621. mReporter.ClearError(); ReleaseScanner(); if (success) { Debug.Assert(aSelectorList != null, "Should have list!"); return nsresult.OK; } Debug.Assert(aSelectorList == null, "Shouldn't have list!"); return nsresult.ERROR_DOM_SYNTAX_ERR; }
internal void InitScanner(nsCSSScanner aScanner, ErrorReporter aReporter, Uri aSheetURI, Uri aBaseURI, nsIPrincipal aSheetPrincipal) { if (!(!mHTMLMediaMode)) throw new ArgumentException("Bad initial state"); if (!(!mParsingCompoundProperty)) throw new ArgumentException("Bad initial state"); if (!(mScanner == null)) throw new ArgumentException("already have scanner"); mScanner = aScanner; mReporter = aReporter; mScanner.SetErrorReporter(mReporter); mBaseURI = aBaseURI; mSheetURI = aSheetURI; mSheetPrincipal = aSheetPrincipal; mHavePushBack = false; }
internal nsresult ParseProperty(nsCSSProperty aPropID, string aPropValue, Uri aSheetURI, Uri aBaseURI, nsIPrincipal aSheetPrincipal, Declaration aDeclaration, ref bool aChanged, bool aIsImportant, bool aIsSVGMode) { if (aSheetPrincipal == null) throw new ArgumentException("Must have principal here!"); if (aBaseURI == null) throw new ArgumentException("need base URI"); if (aDeclaration == null) throw new ArgumentException("Need declaration to parse into!"); mData.AssertInitialState(); mTempData.AssertInitialState(); aDeclaration.AssertMutable(); var scanner = new nsCSSScanner(aPropValue, 0); var reporter = new ErrorReporter(scanner, mSheet, mChildLoader, aSheetURI); InitScanner(scanner, reporter, aSheetURI, aBaseURI, aSheetPrincipal); mSection = nsCSSSection.General; scanner.SetSVGMode(aIsSVGMode); aChanged = false; // Check for unknown or preffed off properties if (nsCSSProperty.Unknown == aPropID || !nsCSSProps.IsEnabled(aPropID)) { string propName = nsCSSProps.GetStringValue(aPropID); { if (!mSuppressErrors) mReporter.ReportUnexpected("PEUnknownProperty", propName); }; { if (!mSuppressErrors) mReporter.ReportUnexpected("PEDeclDropped"); }; mReporter.OutputError(); ReleaseScanner(); return nsresult.OK; } bool parsedOK = ParseProperty(aPropID); // We should now be at EOF if (parsedOK && GetToken(true)) { { if (!mSuppressErrors) mReporter.ReportUnexpected("PEExpectEndValue", mToken); }; parsedOK = false; } if (!parsedOK) { string propName = nsCSSProps.GetStringValue(aPropID); { if (!mSuppressErrors) mReporter.ReportUnexpected("PEValueParsingError", propName); }; { if (!mSuppressErrors) mReporter.ReportUnexpected("PEDeclDropped"); }; mReporter.OutputError(); mTempData.ClearProperty(aPropID); } else { // We know we don't need to force a ValueAppended call for the new // value. So if we are not processing a shorthand, and there's // already a value for this property in the declaration at the // same importance level, then we can just copy our parsed value // directly into the declaration without going through the whole // expand/compress thing. if (!aDeclaration.TryReplaceValue(aPropID, aIsImportant, mTempData, ref aChanged)) { // Do it the slow way aDeclaration.ExpandTo(mData); aChanged = mData.TransferFromBlock(mTempData, aPropID, aIsImportant, true, false, aDeclaration); aDeclaration.CompressFrom(mData); } mReporter.ClearError(); } mTempData.AssertInitialState(); ReleaseScanner(); return nsresult.OK; }
internal nsresult ParseMediaList(string aBuffer, Uri aURI, // for error reporting uint32_t aLineNumber, // for error reporting nsMediaList aMediaList, bool aHTMLMode) { // XXX Are there cases where the caller wants to keep what it already // has in case of parser error? If GatherMedia ever changes to return // a value other than true, we probably should avoid modifying aMediaList. aMediaList.Clear(); // fake base URI since media lists don't have URIs in them var scanner = new nsCSSScanner(aBuffer, aLineNumber); var reporter = new ErrorReporter(scanner, mSheet, mChildLoader, aURI); InitScanner(scanner, reporter, aURI, aURI, null); mHTMLMediaMode = aHTMLMode; // XXXldb We need to make the scanner not skip CSS comments! (Or // should we?) // For aHTMLMode, we used to follow the parsing rules in // http://www.w3.org/TR/1999/REC-html401-19991224/types.html#type-media-descriptors // which wouldn't work for media queries since they remove all but the // first word. However, they're changed in // http://www.whatwg.org/specs/web-apps/current-work/multipage/section-document.html#media2 // (as of 2008-05-29) which says that the media attribute just points // to a media query. (The main substative difference is the relative // precedence of commas and paretheses.) bool parsedOK = GatherMedia(aMediaList, false); Debug.Assert(parsedOK, "GatherMedia returned false; we probably want to avoid trashing aMediaList"); mReporter.ClearError(); ReleaseScanner(); mHTMLMediaMode = false; return nsresult.OK; }
internal bool ParseKeyframeSelectorString(string aSelectorString, Uri aURI, // for error reporting uint32_t aLineNumber, // for error reporting List<float> aSelectorList) { Debug.Assert(aSelectorList.IsEmpty(), "given list should start empty"); var scanner = new nsCSSScanner(aSelectorString, aLineNumber); var reporter = new ErrorReporter(scanner, mSheet, mChildLoader, aURI); InitScanner(scanner, reporter, aURI, aURI, null); bool success = ParseKeyframeSelectorList(aSelectorList) && // must consume entire input string !GetToken(true); mReporter.OutputError(); ReleaseScanner(); if (success) { Debug.Assert(!aSelectorList.IsEmpty(), "should not be empty"); } else { aSelectorList.Clear(); } return success; }
internal nsCSSKeyframeRule ParseKeyframeRule(string aBuffer, Uri aURI, uint32_t aLineNumber) { var scanner = new nsCSSScanner(aBuffer, aLineNumber); var reporter = new ErrorReporter(scanner, mSheet, mChildLoader, aURI); InitScanner(scanner, reporter, aURI, aURI, null); nsCSSKeyframeRule result = ParseKeyframeRule(); if (GetToken(true)) { // extra garbage at the end result = null; } mReporter.OutputError(); ReleaseScanner(); return result; }