Parser.Blocks.cs 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858
  1. using System;
  2. using System.Text;
  3. using System.Collections.Generic;
  4. using ExCSS.Model;
  5. using ExCSS.Model.TextBlocks;
  6. #pragma warning disable
  7. namespace ExCSS
  8. {
  9. public partial class Parser
  10. {
  11. private bool ParseTokenBlock(Block token)
  12. {
  13. switch (_parsingContext)
  14. {
  15. case ParsingContext.DataBlock:
  16. return ParseSymbol(token);
  17. case ParsingContext.InSelector:
  18. return ParseSelector(token);
  19. case ParsingContext.InDeclaration:
  20. return ParseDeclaration(token);
  21. case ParsingContext.AfterProperty:
  22. return ParsePostProperty(token);
  23. case ParsingContext.BeforeValue:
  24. return ParseValue(token);
  25. case ParsingContext.InValuePool:
  26. return ParseValuePool(token);
  27. case ParsingContext.InValueList:
  28. return ParseValueList(token);
  29. case ParsingContext.InSingleValue:
  30. return ParseSingleValue(token);
  31. case ParsingContext.ValueImportant:
  32. return ParseImportant(token);
  33. case ParsingContext.AfterValue:
  34. return ParsePostValue(token);
  35. case ParsingContext.InMediaList:
  36. return ParseMediaList(token);
  37. case ParsingContext.InMediaValue:
  38. return ParseMediaValue(token);
  39. case ParsingContext.BeforeImport:
  40. return ParseImport(token);
  41. case ParsingContext.AfterInstruction:
  42. return ParsePostInstruction(token);
  43. case ParsingContext.BeforeCharset:
  44. return ParseCharacterSet(token);
  45. case ParsingContext.BeforeNamespacePrefix:
  46. return ParseLeadingPrefix(token);
  47. case ParsingContext.AfterNamespacePrefix:
  48. return ParseNamespace(token);
  49. case ParsingContext.InCondition:
  50. return ParseCondition(token);
  51. case ParsingContext.InUnknown:
  52. return ParseUnknown(token);
  53. case ParsingContext.InKeyframeText:
  54. return ParseKeyframeText(token);
  55. case ParsingContext.BeforePageSelector:
  56. return ParsePageSelector(token);
  57. case ParsingContext.BeforeDocumentFunction:
  58. return ParsePreDocumentFunction(token);
  59. case ParsingContext.InDocumentFunction:
  60. return ParseDocumentFunction(token);
  61. case ParsingContext.AfterDocumentFunction:
  62. return ParsePostDocumentFunction(token);
  63. case ParsingContext.BetweenDocumentFunctions:
  64. return ParseDocumentFunctions(token);
  65. case ParsingContext.BeforeKeyframesName:
  66. return ParseKeyframesName(token);
  67. case ParsingContext.BeforeKeyframesData:
  68. return ParsePreKeyframesData(token);
  69. case ParsingContext.KeyframesData:
  70. return ParseKeyframesData(token);
  71. case ParsingContext.BeforeFontFace:
  72. return ParseFontface(token);
  73. case ParsingContext.InHexValue:
  74. return ParseHexValue(token);
  75. case ParsingContext.InFunction:
  76. return ParseValueFunction(token);
  77. default:
  78. return false;
  79. }
  80. }
  81. private bool ParseSymbol(Block token)
  82. {
  83. if (token.GrammarSegment == GrammarSegment.AtRule)
  84. {
  85. switch (((SymbolBlock)token).Value)
  86. {
  87. case RuleTypes.Media:
  88. {
  89. AddRuleSet(new MediaRule());
  90. SetParsingContext(ParsingContext.InMediaList);
  91. break;
  92. }
  93. case RuleTypes.Page:
  94. {
  95. AddRuleSet(new PageRule());
  96. //SetParsingContext(ParsingContext.InSelector);
  97. SetParsingContext(ParsingContext.BeforePageSelector);
  98. break;
  99. }
  100. case RuleTypes.Import:
  101. {
  102. AddRuleSet(new ImportRule());
  103. SetParsingContext(ParsingContext.BeforeImport);
  104. break;
  105. }
  106. case RuleTypes.FontFace:
  107. {
  108. AddRuleSet(new FontFaceRule());
  109. //SetParsingContext(ParsingContext.InDeclaration);
  110. SetParsingContext(ParsingContext.BeforeFontFace);
  111. break;
  112. }
  113. case RuleTypes.CharacterSet:
  114. {
  115. AddRuleSet(new CharacterSetRule());
  116. SetParsingContext(ParsingContext.BeforeCharset);
  117. break;
  118. }
  119. case RuleTypes.Namespace:
  120. {
  121. AddRuleSet(new NamespaceRule());
  122. SetParsingContext(ParsingContext.BeforeNamespacePrefix);
  123. break;
  124. }
  125. case RuleTypes.Supports:
  126. {
  127. _buffer = new StringBuilder();
  128. AddRuleSet(new SupportsRule());
  129. SetParsingContext(ParsingContext.InCondition);
  130. break;
  131. }
  132. case RuleTypes.Keyframes:
  133. {
  134. AddRuleSet(new KeyframesRule());
  135. SetParsingContext(ParsingContext.BeforeKeyframesName);
  136. break;
  137. }
  138. case RuleTypes.Document:
  139. {
  140. AddRuleSet(new DocumentRule());
  141. SetParsingContext(ParsingContext.BeforeDocumentFunction);
  142. break;
  143. }
  144. default:
  145. {
  146. _buffer = new StringBuilder();
  147. AddRuleSet(new GenericRule());
  148. SetParsingContext(ParsingContext.InUnknown);
  149. ParseUnknown(token);
  150. break;
  151. }
  152. }
  153. return true;
  154. }
  155. if (token.GrammarSegment == GrammarSegment.CurlyBracketClose)
  156. {
  157. return FinalizeRule();
  158. }
  159. AddRuleSet(new StyleRule());
  160. SetParsingContext(ParsingContext.InSelector);
  161. ParseSelector(token);
  162. return true;
  163. }
  164. private bool ParseUnknown(Block token)
  165. {
  166. switch (token.GrammarSegment)
  167. {
  168. case GrammarSegment.Semicolon:
  169. CastRuleSet<GenericRule>().SetInstruction(_buffer.ToString());
  170. SetParsingContext(ParsingContext.DataBlock);
  171. return FinalizeRule();
  172. case GrammarSegment.CurlyBraceOpen:
  173. CastRuleSet<GenericRule>().SetCondition(_buffer.ToString());
  174. SetParsingContext(ParsingContext.DataBlock);
  175. break;
  176. default:
  177. _buffer.Append(token);
  178. break;
  179. }
  180. return true;
  181. }
  182. private bool ParseSelector(Block token)
  183. {
  184. switch (token.GrammarSegment)
  185. {
  186. case GrammarSegment.CurlyBraceOpen:
  187. {
  188. var rule = CurrentRule as ISupportsSelector;
  189. if (rule != null)
  190. {
  191. rule.Selector = _selectorFactory.GetSelector();
  192. }
  193. SetParsingContext(CurrentRule is StyleRule
  194. ? ParsingContext.InDeclaration
  195. : ParsingContext.DataBlock);
  196. }
  197. break;
  198. case GrammarSegment.CurlyBracketClose:
  199. return false;
  200. default:
  201. _selectorFactory.Apply(token);
  202. break;
  203. }
  204. return true;
  205. }
  206. private bool ParseDeclaration(Block token)
  207. {
  208. if (token.GrammarSegment == GrammarSegment.CurlyBracketClose)
  209. {
  210. FinalizeProperty();
  211. SetParsingContext(CurrentRule is KeyframeRule ? ParsingContext.KeyframesData : ParsingContext.DataBlock);
  212. return FinalizeRule();
  213. }
  214. if (token.GrammarSegment != GrammarSegment.Ident)
  215. {
  216. return false;
  217. }
  218. AddProperty(new Property(((SymbolBlock)token).Value));
  219. SetParsingContext(ParsingContext.AfterProperty);
  220. return true;
  221. }
  222. private bool ParsePostInstruction(Block token)
  223. {
  224. if (token.GrammarSegment != GrammarSegment.Semicolon)
  225. {
  226. return false;
  227. }
  228. SetParsingContext(ParsingContext.DataBlock);
  229. return FinalizeRule();
  230. }
  231. private bool ParseCondition(Block token)
  232. {
  233. switch (token.GrammarSegment)
  234. {
  235. case GrammarSegment.CurlyBraceOpen:
  236. CastRuleSet<SupportsRule>().Condition = _buffer.ToString();
  237. SetParsingContext(ParsingContext.DataBlock);
  238. break;
  239. default:
  240. _buffer.Append(token);
  241. break;
  242. }
  243. return true;
  244. }
  245. private bool ParseLeadingPrefix(Block token)
  246. {
  247. if (token.GrammarSegment == GrammarSegment.Ident)
  248. {
  249. CastRuleSet<NamespaceRule>().Prefix = ((SymbolBlock)token).Value;
  250. SetParsingContext(ParsingContext.AfterNamespacePrefix);
  251. return true;
  252. }
  253. if (token.GrammarSegment == GrammarSegment.String || token.GrammarSegment == GrammarSegment.Url)
  254. {
  255. CastRuleSet<NamespaceRule>().Uri = ((StringBlock)token).Value;
  256. return true;
  257. }
  258. SetParsingContext(ParsingContext.AfterInstruction);
  259. return ParsePostInstruction(token);
  260. }
  261. private bool ParsePostProperty(Block token)
  262. {
  263. if (token.GrammarSegment == GrammarSegment.Colon)
  264. {
  265. _isFraction = false;
  266. SetParsingContext(ParsingContext.BeforeValue);
  267. return true;
  268. }
  269. if (token.GrammarSegment == GrammarSegment.Semicolon || token.GrammarSegment == GrammarSegment.CurlyBracketClose)
  270. {
  271. ParsePostValue(token);
  272. }
  273. return false;
  274. }
  275. private bool ParseValue(Block token)
  276. {
  277. switch (token.GrammarSegment)
  278. {
  279. case GrammarSegment.Semicolon:
  280. SetParsingContext(ParsingContext.InDeclaration);
  281. break;
  282. case GrammarSegment.CurlyBracketClose:
  283. ParseDeclaration(token);
  284. break;
  285. default:
  286. SetParsingContext(ParsingContext.InSingleValue);
  287. return ParseSingleValue(token);
  288. }
  289. return false;
  290. }
  291. private bool ParseSingleValue(Block token)
  292. {
  293. switch (token.GrammarSegment)
  294. {
  295. case GrammarSegment.Dimension: // "3px"
  296. return AddTerm(new PrimitiveTerm(((UnitBlock)token).Unit, ((UnitBlock)token).Value));
  297. case GrammarSegment.Hash:// "#ffffff"
  298. return ParseSingleValueHexColor(((SymbolBlock)token).Value);
  299. case GrammarSegment.Delimiter: // "#"
  300. return ParseValueDelimiter((DelimiterBlock)token);
  301. case GrammarSegment.Ident: // "auto"
  302. return ParseSingleValueIdent((SymbolBlock)token);
  303. case GrammarSegment.String:// "'some value'"
  304. return AddTerm(new PrimitiveTerm(UnitType.String, ((StringBlock)token).Value));
  305. case GrammarSegment.Url:// "url('http://....')"
  306. return AddTerm(new PrimitiveTerm(UnitType.Uri, ((StringBlock)token).Value));
  307. case GrammarSegment.Percentage: // "10%"
  308. return AddTerm(new PrimitiveTerm(UnitType.Percentage, ((UnitBlock)token).Value));
  309. case GrammarSegment.Number: // "123"
  310. return AddTerm(new PrimitiveTerm(UnitType.Number, ((NumericBlock)token).Value));
  311. case GrammarSegment.Whitespace: // " "
  312. _terms.AddSeparator(GrammarSegment.Whitespace);
  313. SetParsingContext(ParsingContext.InValueList);
  314. return true;
  315. case GrammarSegment.Function: // rgba(...)
  316. _functionBuffers.Push(new FunctionBuffer(((SymbolBlock)token).Value));
  317. SetParsingContext(ParsingContext.InFunction);
  318. return true;
  319. case GrammarSegment.Comma: // ","
  320. _terms.AddSeparator(GrammarSegment.Comma);
  321. SetParsingContext(ParsingContext.InValuePool);
  322. return true;
  323. case GrammarSegment.Semicolon: // ";"
  324. case GrammarSegment.CurlyBracketClose: // "}"
  325. return ParsePostValue(token);
  326. default:
  327. return false;
  328. }
  329. }
  330. private bool ParseValueFunction(Block token)
  331. {
  332. switch (token.GrammarSegment)
  333. {
  334. case GrammarSegment.ParenClose:
  335. SetParsingContext(ParsingContext.InSingleValue);
  336. return AddTerm(_functionBuffers.Pop().Done());
  337. case GrammarSegment.Comma:
  338. _functionBuffers.Peek().Include();
  339. return true;
  340. default:
  341. return ParseSingleValue(token);
  342. }
  343. }
  344. private bool ParseValueList(Block token)
  345. {
  346. switch (token.GrammarSegment)
  347. {
  348. case GrammarSegment.CurlyBracketClose:
  349. case GrammarSegment.Semicolon:
  350. ParsePostValue(token);
  351. break;
  352. case GrammarSegment.Comma:
  353. SetParsingContext(ParsingContext.InValuePool);
  354. break;
  355. default:
  356. SetParsingContext(ParsingContext.InSingleValue);
  357. return ParseSingleValue(token);
  358. }
  359. return true;
  360. }
  361. private bool ParseValuePool(Block token)
  362. {
  363. if (token.GrammarSegment == GrammarSegment.Semicolon || token.GrammarSegment == GrammarSegment.CurlyBracketClose)
  364. {
  365. ParsePostValue(token);
  366. }
  367. else
  368. {
  369. SetParsingContext(ParsingContext.InSingleValue);
  370. return ParseSingleValue(token);
  371. }
  372. return false;
  373. }
  374. private bool ParseHexValue(Block token)
  375. {
  376. switch (token.GrammarSegment)
  377. {
  378. case GrammarSegment.Number:
  379. case GrammarSegment.Dimension:
  380. case GrammarSegment.Ident:
  381. var rest = token.ToString();
  382. if (_buffer.Length + rest.Length <= 6)
  383. {
  384. _buffer.Append(rest);
  385. return true;
  386. }
  387. break;
  388. }
  389. ParseSingleValueHexColor(_buffer.ToString());
  390. SetParsingContext(ParsingContext.InSingleValue);
  391. return ParseSingleValue(token);
  392. }
  393. private bool ParsePostValue(Block token)
  394. {
  395. if (token.GrammarSegment == GrammarSegment.Semicolon)
  396. {
  397. FinalizeProperty();
  398. SetParsingContext(ParsingContext.InDeclaration);
  399. return true;
  400. }
  401. if (token.GrammarSegment == GrammarSegment.CurlyBracketClose)
  402. {
  403. return ParseDeclaration(token);
  404. }
  405. return false;
  406. }
  407. private bool ParseImportant(Block token)
  408. {
  409. if (token.GrammarSegment != GrammarSegment.Ident || ((SymbolBlock)token).Value != "important")
  410. {
  411. return ParsePostValue(token);
  412. }
  413. SetParsingContext(ParsingContext.AfterValue);
  414. _property.Important = true;
  415. return true;
  416. }
  417. private bool ParseValueDelimiter(DelimiterBlock token)
  418. {
  419. switch (token.Value)
  420. {
  421. case Specification.Em:
  422. SetParsingContext(ParsingContext.ValueImportant);
  423. return true;
  424. case Specification.Hash:
  425. _buffer = new StringBuilder();
  426. SetParsingContext(ParsingContext.InHexValue);
  427. return true;
  428. case Specification.Solidus:
  429. _isFraction = true;
  430. return true;
  431. default:
  432. return false;
  433. }
  434. }
  435. private bool ParseSingleValueIdent(SymbolBlock token)
  436. {
  437. if (token.Value != "inherit")
  438. {
  439. return AddTerm(new PrimitiveTerm(UnitType.Ident, token.Value));
  440. }
  441. _terms.AddTerm(Term.Inherit);
  442. SetParsingContext(ParsingContext.AfterValue);
  443. return true;
  444. }
  445. private bool ParseSingleValueHexColor(string color)
  446. {
  447. HtmlColor htmlColor;
  448. if (HtmlColor.TryFromHex(color, out htmlColor))
  449. return AddTerm(htmlColor);
  450. return false;
  451. }
  452. #region Namespace
  453. private bool ParseNamespace(Block token)
  454. {
  455. SetParsingContext(ParsingContext.AfterInstruction);
  456. if (token.GrammarSegment != GrammarSegment.String)
  457. {
  458. return ParsePostInstruction(token);
  459. }
  460. CastRuleSet<NamespaceRule>().Uri = ((StringBlock)token).Value;
  461. return true;
  462. }
  463. #endregion
  464. #region Charset
  465. private bool ParseCharacterSet(Block token)
  466. {
  467. SetParsingContext(ParsingContext.AfterInstruction);
  468. if (token.GrammarSegment != GrammarSegment.String)
  469. {
  470. return ParsePostInstruction(token);
  471. }
  472. CastRuleSet<CharacterSetRule>().Encoding = ((StringBlock)token).Value;
  473. return true;
  474. }
  475. #endregion
  476. #region Import
  477. private bool ParseImport(Block token)
  478. {
  479. if (token.GrammarSegment == GrammarSegment.String || token.GrammarSegment == GrammarSegment.Url)
  480. {
  481. CastRuleSet<ImportRule>().Href = ((StringBlock)token).Value;
  482. SetParsingContext(ParsingContext.InMediaList);
  483. return true;
  484. }
  485. SetParsingContext(ParsingContext.AfterInstruction);
  486. return false;
  487. }
  488. #endregion
  489. #region Font Face
  490. private bool ParseFontface(Block token)
  491. {
  492. if (token.GrammarSegment == GrammarSegment.CurlyBraceOpen)
  493. {
  494. SetParsingContext(ParsingContext.InDeclaration);
  495. return true;
  496. }
  497. return false;
  498. }
  499. #endregion
  500. #region Keyframes
  501. private bool ParseKeyframesName(Block token)
  502. {
  503. //SetParsingContext(ParsingContext.BeforeKeyframesData);
  504. if (token.GrammarSegment == GrammarSegment.Ident)
  505. {
  506. CastRuleSet<KeyframesRule>().Identifier = ((SymbolBlock)token).Value;
  507. return true;
  508. }
  509. if (token.GrammarSegment == GrammarSegment.CurlyBraceOpen)
  510. {
  511. SetParsingContext(ParsingContext.KeyframesData);
  512. return true;
  513. }
  514. return false;
  515. }
  516. private bool ParsePreKeyframesData(Block token)
  517. {
  518. if (token.GrammarSegment != GrammarSegment.CurlyBraceOpen)
  519. {
  520. return false;
  521. }
  522. SetParsingContext(ParsingContext.BeforeKeyframesData);
  523. return true;
  524. }
  525. private bool ParseKeyframesData(Block token)
  526. {
  527. if (token.GrammarSegment == GrammarSegment.CurlyBracketClose)
  528. {
  529. SetParsingContext(ParsingContext.DataBlock);
  530. return FinalizeRule();
  531. }
  532. _buffer = new StringBuilder();
  533. return ParseKeyframeText(token);
  534. }
  535. private bool ParseKeyframeText(Block token)
  536. {
  537. if (token.GrammarSegment == GrammarSegment.CurlyBraceOpen)
  538. {
  539. SetParsingContext(ParsingContext.InDeclaration);
  540. return true;
  541. }
  542. if (token.GrammarSegment == GrammarSegment.CurlyBracketClose)
  543. {
  544. ParseKeyframesData(token);
  545. return false;
  546. }
  547. var frame = new KeyframeRule
  548. {
  549. Value = token.ToString()
  550. };
  551. CastRuleSet<KeyframesRule>().Declarations.Add(frame);
  552. _activeRuleSets.Push(frame);
  553. return true;
  554. }
  555. #endregion
  556. #region Page
  557. private bool ParsePageSelector(Block token)
  558. {
  559. if (token.GrammarSegment == GrammarSegment.Colon || token.GrammarSegment == GrammarSegment.Whitespace)
  560. {
  561. return true;
  562. }
  563. if (token.GrammarSegment == GrammarSegment.Ident)
  564. {
  565. CastRuleSet<PageRule>().Selector = new SimpleSelector(token.ToString());
  566. return true;
  567. }
  568. if (token.GrammarSegment == GrammarSegment.CurlyBraceOpen)
  569. {
  570. SetParsingContext(ParsingContext.InDeclaration);
  571. return true;
  572. }
  573. return false;
  574. }
  575. #endregion
  576. #region Document
  577. private bool ParsePreDocumentFunction(Block token)
  578. {
  579. switch (token.GrammarSegment)
  580. {
  581. case GrammarSegment.Url:
  582. CastRuleSet<DocumentRule>().Conditions.Add(new KeyValuePair<DocumentFunction, string>(DocumentFunction.Url, ((StringBlock)token).Value));
  583. break;
  584. case GrammarSegment.UrlPrefix:
  585. CastRuleSet<DocumentRule>().Conditions.Add(new KeyValuePair<DocumentFunction, string>(DocumentFunction.UrlPrefix, ((StringBlock)token).Value));
  586. break;
  587. case GrammarSegment.Domain:
  588. CastRuleSet<DocumentRule>().Conditions.Add(new KeyValuePair<DocumentFunction, string>(DocumentFunction.Domain, ((StringBlock)token).Value));
  589. break;
  590. case GrammarSegment.Function:
  591. if (string.Compare(((SymbolBlock)token).Value, "regexp", StringComparison.OrdinalIgnoreCase) == 0)
  592. {
  593. SetParsingContext(ParsingContext.InDocumentFunction);
  594. return true;
  595. }
  596. SetParsingContext(ParsingContext.AfterDocumentFunction);
  597. return false;
  598. default:
  599. SetParsingContext(ParsingContext.DataBlock);
  600. return false;
  601. }
  602. SetParsingContext(ParsingContext.BetweenDocumentFunctions);
  603. return true;
  604. }
  605. private bool ParseDocumentFunction(Block token)
  606. {
  607. SetParsingContext(ParsingContext.AfterDocumentFunction);
  608. if (token.GrammarSegment != GrammarSegment.String) return false;
  609. CastRuleSet<DocumentRule>().Conditions.Add(new KeyValuePair<DocumentFunction, string>(DocumentFunction.RegExp, ((StringBlock)token).Value));
  610. return true;
  611. }
  612. private bool ParsePostDocumentFunction(Block token)
  613. {
  614. SetParsingContext(ParsingContext.BetweenDocumentFunctions);
  615. return token.GrammarSegment == GrammarSegment.ParenClose;
  616. }
  617. private bool ParseDocumentFunctions(Block token)
  618. {
  619. if (token.GrammarSegment == GrammarSegment.Comma)
  620. {
  621. SetParsingContext(ParsingContext.BeforeDocumentFunction);
  622. return true;
  623. }
  624. if (token.GrammarSegment == GrammarSegment.CurlyBraceOpen)
  625. {
  626. SetParsingContext(ParsingContext.DataBlock);
  627. return true;
  628. }
  629. SetParsingContext(ParsingContext.DataBlock);
  630. return false;
  631. }
  632. #endregion
  633. #region Media
  634. private bool ParseMediaList(Block token)
  635. {
  636. if (token.GrammarSegment == GrammarSegment.Semicolon)
  637. {
  638. FinalizeRule();
  639. SetParsingContext(ParsingContext.DataBlock);
  640. return true;
  641. }
  642. _buffer = new StringBuilder();
  643. SetParsingContext(ParsingContext.InMediaValue);
  644. return ParseMediaValue(token);
  645. }
  646. private bool ParseMediaValue(Block token)
  647. {
  648. switch (token.GrammarSegment)
  649. {
  650. case GrammarSegment.CurlyBraceOpen:
  651. case GrammarSegment.Semicolon:
  652. {
  653. var container = CurrentRule as ISupportsMedia;
  654. var medium = _buffer.ToString();
  655. if (container != null)
  656. {
  657. container.Media.AppendMedium(medium);
  658. }
  659. if (CurrentRule is ImportRule)
  660. {
  661. return ParsePostInstruction(token);
  662. }
  663. SetParsingContext(ParsingContext.DataBlock);
  664. return token.GrammarSegment == GrammarSegment.CurlyBraceOpen;
  665. }
  666. case GrammarSegment.Comma:
  667. {
  668. var container = CurrentRule as ISupportsMedia;
  669. if (container != null)
  670. {
  671. container.Media.AppendMedium(_buffer.ToString());
  672. }
  673. _buffer.Length = 0;
  674. return true;
  675. }
  676. case GrammarSegment.Whitespace:
  677. {
  678. _buffer.Append(' ');
  679. return true;
  680. }
  681. default:
  682. {
  683. _buffer.Append(token);
  684. return true;
  685. }
  686. }
  687. }
  688. #endregion
  689. }
  690. }
  691. #pragma warning restore