private async Task HandleBlockChainResponse(string message) { var receiveBlocks = JsonConvert.DeserializeObject <List <SimpleBlock> >(message); receiveBlocks.OrderBy(block => block.Index); SimpleBlock latestBlockReceived = receiveBlocks.Last(); SimpleBlock latestBlock = blockChain.LatestBlock; if (latestBlockReceived.Index > latestBlock.Index) { if (latestBlock.Hash == latestBlockReceived.PreviousHash) { logger.LogInformation("We can append the received block to our chain"); blockChain.Add(latestBlockReceived); await Broadcast(ResponseLatestMessage()); } else if (receiveBlocks.Count == 1) { logger.LogInformation("We have to query the chain from our peer"); await Broadcast(QueryAllMessage()); } else { blockChain.ReplaceChain(receiveBlocks); } } else { logger.LogInformation("received blockchain is not longer than received blockchain. Do nothing"); } }
public void Chain_should_reorg_if_disconnect() { var root = new SimpleBlock("0"); var chain = new Chain <SimpleBlock>(root); var block1 = new SimpleBlock("1"); block1.PreviousChainNodeID = root.ID; chain.ConnectChainNode(block1); var block2 = new SimpleBlock("2"); block2.PreviousChainNodeID = root.ID; var block3 = new SimpleBlock("3"); block3.PreviousChainNodeID = block2.ID; chain.ConnectChainNode(block2); chain.ConnectChainNode(block3); chain.ReversedActiveChain.Count().Should().Be(3); chain.ReversedActiveChain.First().Should().Be(block3); chain.ReversedActiveChain.First().Height.Should().Be(2); chain.ActiveChainChangeEvent += (object sender, ActiveChainChangeEventArgs e) => { e.Old.ID.Should().Be("3"); e.New.ID.Should().Be("1"); }; chain.DisconnectChainNode(block3); chain.DisconnectChainNode(block2); chain.ReversedActiveChain.Count().Should().Be(2); chain.ReversedActiveChain.First().Should().Be(block1); chain.ReversedActiveChain.First().Height.Should().Be(1); }
protected override void VisitSimpleBlock(SimpleBlock block, ExplodedGraphNode node) { var newProgramState = CleanStateAfterBlock(node.ProgramState, block); if (block is ForeachCollectionProducerBlock) { newProgramState = newProgramState.PopValue(); EnqueueAllSuccessors(block, newProgramState); return; } var forInitializerBlock = block as ForInitializerBlock; if (forInitializerBlock != null) { newProgramState = newProgramState.PopValues( forInitializerBlock.ForNode.Initializers.Count); newProgramState = newProgramState.PushValues( Enumerable .Range(0, forInitializerBlock.ForNode.Incrementors.Count) .Select(i => new SymbolicValue())); EnqueueAllSuccessors(forInitializerBlock, newProgramState); return; } base.VisitSimpleBlock(block, node); }
public override ILineObject Generate(GenerationEnvironment env) { var ret = new SimpleBlock(new ILineObject[] { _ClearLabel.Generate(env), _InitCount.Generate(env), _SetMotion.Generate(env), _AdjustDirection.Generate(env), }).Statement(); if (AutoCancel) { if (IsInAir) { ret = new SimpleBlock(new ILineObject[] { ret, _SitCancel.Generate(env), }).Statement(); } else { ret = new SimpleBlock(new ILineObject[] { ret, _FallCancel.Generate(env), }).Statement(); } } return(ret); }
/// <summary> /// 5.4.6. Consume a component value /// </summary> /// <returns></returns> private ComponentValue ConsumeComponentValue() { //Consume the next input token. cssToken token = ConsumeNextToken(); //If the current input token is a <{-token>, <[-token>, or <(-token>, consume a simple block and return it. if (token.Type == enumTokenType.curly_bracket_left || token.Type == enumTokenType.square_bracket_left || token.Type == enumTokenType.round_bracket_left) { SimpleBlock simpleblock = ConsumeSimpleBlock(); simpleblock.startindex = token.startIndex; return(simpleblock); } //Otherwise, if the current input token is a <function-token>, consume a function and return it. else if (token.Type == enumTokenType.function) { Function func = ConsumeFunction(); func.startindex = token.startIndex; return(func); } else { //Otherwise, return the current input token. PreservedToken preservedtoken = new PreservedToken(); preservedtoken.token = token; preservedtoken.startindex = token.startIndex; preservedtoken.endindex = token.endIndex; return(preservedtoken); } }
public void SendBlock(IBlock Block) { switch (Block.Type) { case BlockType.SimpleBlock: SimpleBlock sb = Block as SimpleBlock; Send(WorldMap.Key, 0, Block.Position.X, Block.Position.Y, Block.ID); break; case BlockType.BackgroundBlock: BackgroundBlock bb = Block as BackgroundBlock; Send(WorldMap.Key, 1, Block.Position.X, Block.Position.Y, Block.ID); break; case BlockType.RotatableBlock: RotatableBlock rb = Block as RotatableBlock; Send(WorldMap.Key, 0, Block.Position.X, Block.Position.Y, Block.ID, (int)rb.Rotation); break; case BlockType.ValuedBlock: ValuedBlock vb = Block as ValuedBlock; Send(WorldMap.Key, 0, Block.Position.X, Block.Position.Y, Block.ID, vb.Value); break; case BlockType.PortalBlock: PortalBlock pb = Block as PortalBlock; Send(WorldMap.Key, 0, Block.Position.X, Block.Position.Y, Block.ID, (int)pb.Rotation, pb.Identificator, pb.Target); break; } }
/// <summary> /// 5.4.3. Consume a qualified rule /// </summary> /// <returns></returns> private QualifiedRule ConsumeQualifiedRule() { //To consume a qualified rule: //Create a new qualified rule with its prelude initially set to an empty list, and its value initially set to nothing. QualifiedRule rule = new QualifiedRule(); // set operation is performed by CTOR. int startindex = -1; cssToken token = null; while (true) { //Repeatedly consume the next input token: token = ConsumeNextToken(); if (startindex == -1) { startindex = token.startIndex; } //<EOF-token> if (token.Type == enumTokenType.EOF) { //This is a parse error. Return nothing. return(null); } //<{-token> else if (token.Type == enumTokenType.curly_bracket_left) { //Consume a simple block and assign it to the qualified rule’s block. Return the qualified rule. SimpleBlock block = ConsumeSimpleBlock(); block.startindex = token.startIndex; rule.block = block; rule.startindex = startindex; rule.endindex = block.endindex; return(rule); } //simple block with an associated token of <{-token> //???????TODO: this must be an mistake in the syntax paper.. //Assign the block to the qualified rule’s block. Return the qualified rule. //anything else else { //Reconsume the current input token. Consume a component value. Append the returned value to the qualified rule’s prelude. ReconsumeToken(); ComponentValue value = ConsumeComponentValue(); rule.prelude.Add(value); } } }
public void Chain_should_not_connect_root_block() { var chain = this.CreateSingleChain(); var root = new SimpleBlock("0"); Action action = () => chain.ConnectChainNode(root); action.Should().Throw <Exception>(); }
protected override void VisitSimpleBlock(SimpleBlock block, ExplodedGraphNode node) { var newProgramState = node.ProgramState; var usingFinalizerBlock = block as UsingEndBlock; if (usingFinalizerBlock != null) { foreach (var explodedGraphCheck in explodedGraphChecks) { newProgramState = explodedGraphCheck.PreProcessUsingStatement(node.ProgramPoint, newProgramState); } newProgramState = CleanStateAfterBlock(newProgramState, block); EnqueueAllSuccessors(block, newProgramState); return; } newProgramState = CleanStateAfterBlock(newProgramState, block); if (block is ForeachCollectionProducerBlock) { newProgramState = newProgramState.PopValue(); EnqueueAllSuccessors(block, newProgramState); return; } var forInitializerBlock = block as ForInitializerBlock; if (forInitializerBlock != null) { newProgramState = newProgramState.PopValues( forInitializerBlock.ForNode.Initializers.Count); newProgramState = newProgramState.PushValues( Enumerable .Range(0, forInitializerBlock.ForNode.Incrementors.Count) .Select(i => new SymbolicValue())); EnqueueAllSuccessors(forInitializerBlock, newProgramState); return; } var lockBlock = block as LockBlock; if (lockBlock != null) { newProgramState = newProgramState.PopValue(); newProgramState = newProgramState.RemoveSymbols(IsFieldSymbol); EnqueueAllSuccessors(block, newProgramState); return; } base.VisitSimpleBlock(block, node); }
public void HashTest() { var block = new SimpleBlock(2, "2", 0, "new block"); var hashProvider = new SHA256HashProvider(); hashProvider.Hash(block); Assert.Equal(block.Hash, "b77f43514bcd6c8c963b94c0bb66cbd6da8f5606599f9a32581d22368df02a81"); }
/// <summary> /// 5.4.7. Consume a simple block /// </summary> /// <returns></returns> private SimpleBlock ConsumeSimpleBlock() { //The ending token is the mirror variant of the current input token. (E.g. if it was called with <[-token>, the ending token is <]-token>.) enumTokenType endTokenType = enumTokenType.curly_bracket_right; if (currentToken.Type == enumTokenType.curly_bracket_left) { endTokenType = enumTokenType.curly_bracket_right; } else if (currentToken.Type == enumTokenType.round_bracket_left) { endTokenType = enumTokenType.round_bracket_right; } else if (currentToken.Type == enumTokenType.square_bracket_left) { endTokenType = enumTokenType.square_bracket_right; } //Create a simple block with its associated token set to the current input token and with a value with is initially an empty list. SimpleBlock simpleblock = new SimpleBlock(); simpleblock.token = currentToken; cssToken token; while (true) { token = ConsumeNextToken(); //Repeatedly consume the next input token and process it as follows: //<EOF-token> //ending token if (token.Type == enumTokenType.EOF || token.Type == endTokenType) { //Return the block. simpleblock.endindex = token.endIndex; if (token.Type == enumTokenType.EOF) { simpleblock.endindex = simpleblock.endindex - 1; } return(simpleblock); } //anything else else { //Reconsume the current input token. Consume a component value and append it to the value of the block. ReconsumeToken(); ComponentValue value = ConsumeComponentValue(); simpleblock.value.Add(value); } } }
public void Chain_should_not_connect_dangling_block() { var chain = this.CreateSingleChain(); var danglingBlock = new SimpleBlock("_0"); danglingBlock.PreviousChainNodeID = "_1"; Action action = () => chain.ConnectChainNode(danglingBlock); action.Should().ThrowExactly <DanglingChainNodeException>() .Where(e => e.Node.ID == "_0"); }
public void Chain_should_not_connect_dup_block() { var chain = this.CreateSingleChain(); var block = new SimpleBlock("8"); block.PreviousChainNodeID = "7"; Action action = () => chain.ConnectChainNode(block); action.Should().Throw <DuplicateChainNodeException>() .Where(e => e.Node == block); }
protected virtual void VisitSimpleBlock(SimpleBlock block, ExplodedGraphNode node) { var newProgramState = CleanStateAfterBlock(node.ProgramState, block); if (block is JumpBlock jumpBlock && IsValueConsumingStatement(jumpBlock.JumpNode)) { newProgramState = newProgramState.PopValue(); } EnqueueAllSuccessors(block, newProgramState); }
public async void Post([FromBody] string value) { SimpleBlock lastBlock = _blockChain.LatestBlock; SimpleBlock newBlock = _blockFactory.CreateBlock(lastBlock, value); _blockChain.Add(newBlock); await _p2PService.Broadcast(_p2PService.ResponseLatestMessage()); string s = JsonConvert.SerializeObject(newBlock); _logger.LogInformation("Block added: " + s); }
protected override void VisitSimpleBlock(SimpleBlock block, ExplodedGraphNode node) { var newProgramState = node.ProgramState; if (block is UsingEndBlock usingFinalizerBlock) { newProgramState = InvokeChecks(newProgramState, (ps, check) => check.PreProcessUsingStatement(node.ProgramPoint, ps)); newProgramState = CleanStateAfterBlock(newProgramState, block); EnqueueAllSuccessors(block, newProgramState); return; } newProgramState = CleanStateAfterBlock(newProgramState, block); if (block is ForeachCollectionProducerBlock) { newProgramState = newProgramState.PopValue(); EnqueueAllSuccessors(block, newProgramState); return; } if (block is ForInitializerBlock forInitializerBlock) { newProgramState = newProgramState.PopValues( forInitializerBlock.ForNode.Initializers.Count); newProgramState = newProgramState.PushValues( Enumerable .Range(0, forInitializerBlock.ForNode.Incrementors.Count) .Select(i => new SymbolicValue())); EnqueueAllSuccessors(forInitializerBlock, newProgramState); return; } if (block is LockBlock lockBlock) { newProgramState = newProgramState.PopValue(); newProgramState = newProgramState.RemoveSymbols(IsFieldSymbol); EnqueueAllSuccessors(block, newProgramState); return; } if (block is JumpBlock jumpBlock && jumpBlock.JumpNode.IsKind(SyntaxKind.YieldReturnStatement)) { newProgramState = newProgramState.RemoveSymbols(IsFieldSymbol); } base.VisitSimpleBlock(block, node); }
public static IItemWriter <T, AnyContent> HtmlContent <T>( this IItemWriter <T, AnyContent> target, string html) where T : AnyContentElement { var htmlBlock = new SimpleBlock(); htmlBlock.Value = html; htmlBlock.Helper = target.Helper; htmlBlock.DisableEncoding = true; target.Item.AddContent(htmlBlock); return(target); }
public void VerifyTest() { var blockWithValidHash = new SimpleBlock(2, "2", 0, "new block", "b77f43514bcd6c8c963b94c0bb66cbd6da8f5606599f9a32581d22368df02a81"); var blockWithInvalidHash = new SimpleBlock(2, "2", 0, "new block", "b22f43514bcd6c8c963b94c0bb66cbd6da8f5606599f9a32581d22322df02a22"); var hashProvider = new SHA256HashProvider(); var validBlockResult = hashProvider.Verify(blockWithValidHash); var invalidBlockResult = hashProvider.Verify(blockWithInvalidHash); Assert.True(validBlockResult); Assert.False(invalidBlockResult); }
public Vector3 GetBlockCenter(Vector3 query, int level, IBlock block) { if (level == block.Level - 1) { int id = BlockUtility.FindSubArea(block, query); return(BlockUtility.ChildPositions(block)[id]); } else { int id = BlockUtility.FindSubArea(block, query); Vector3 subcenter = BlockUtility.ChildPositions(block)[id]; IBlock b = new SimpleBlock(subcenter, block.Level - 1); return(GetBlockCenter(query, level, b)); } }
// TODO: Find an easier/clearer/faster way to do this public IEnumerable <StatementNode> Visit(SimpleBlock block) // To extract values from a block, we extract every value from each statement and then return them. // However, it's not as straightforward as it sounds, since we have an array of statements, and each // statement will return an array of ValueNodes. Means we end up with a IEnumerable<StatementNode>[], which we need to flatten // into a IEnumerable<StatementNode> before returning. In code that gives : // // - Content.Select(ExtractValue) applies the ValueExtractor.ExtractValue method to each StatementNode in the block, // which returns a IEnumerable<StatementNode> for each statement in Content. // => returns a IEnumerable<StatementNode>[] // // - SelectMany(node => node) transforms the IEnumerable<StatementNode>[] returned by the previous operation into a lat IEnumerable<StatementNode> // => returns a IEnumerable<StatementNode> => block.Content .Select(Flatten) .SelectMany(node => node);
private Chain <SimpleBlock> CreateSingleChain() { var block = new SimpleBlock("0"); block.Height = 0; var chain = new Chain <SimpleBlock>(block); for (int i = 1; i != 10; ++i) { block = new SimpleBlock(i.ToString()); block.PreviousChainNodeID = (i - 1).ToString(); chain.ConnectChainNode(block); } return(chain); }
public override bool Equals(System.Object Obj) { if (Obj == null) { return(false); } SimpleBlock Block = Obj as SimpleBlock; if ((System.Object)Block == null) { return(false); } return(this == Block); }
public static GraphNode ToGraphNode(SimpleBlock block) { var root = new GraphNode(block.GetHashCode(), "\"block\""); root.AddProperty("color", "darkviolet"); root.AddProperty("tooltip", nameof(SimpleBlock)); foreach (var statement in block.Content) { var statementNode = ToGraphNode((dynamic)statement); statementNode.AddProperty("tooltip", "statement"); root.AddNode(statementNode); } return(root); }
public bool IsSameAs(IBlock Block) { if (this.Type == Block.Type) { SimpleBlock SBlock = Block as SimpleBlock; if (SBlock == this) { return(true); } else { return(false); } } else { return(false); } }
public static IItemWriter <T, AnyContent> Content <T>( this IItemWriter <T, AnyContent> target, object value) where T : AnyContentElement { var itemWriter = value as IItemWriter; if (itemWriter != null) { target.Item.AddContent(itemWriter.Item); } else { var block = new SimpleBlock(); block.Value = value; block.Helper = target.Helper; target.Item.AddContent(block); } return(target); }
public void IsValidNewBlockTest() { var hasher = new SHA256HashProvider(); var factory = new SimpleBlockFactory(hasher); var blockchain = new SimpleBlockChain(hasher, factory); var genesisBlock = factory.CreateGenesisBlock(); var blockWithBadIndex = new SimpleBlock(0, "1", 0, "new block", "0"); Assert.False(blockchain.IsValidNewBlock(genesisBlock, blockWithBadIndex)); var blockWithBadHash = new SimpleBlock(1, "1", 0, "new block", "VERY BAD HASH"); Assert.False(blockchain.IsValidNewBlock(genesisBlock, blockWithBadHash)); var validBlock = new SimpleBlock(2, "2", 0, "new block"); hasher.Hash(validBlock); Assert.False(blockchain.IsValidNewBlock(genesisBlock, blockWithBadHash)); }
/// <summary> /// 5.4.2. Consume an at-rule /// </summary> /// <returns></returns> private AtRule ConsumeAtRule() { //To consume an at-rule: //Create a new at-rule with its name set to the value of the current input token, its prelude initially set to an empty list, and its value initially set to nothing. AtRule rule = new AtRule(); int startindex = -1; cssToken token = null; while (true) { //Repeatedly consume the next input token: token = ConsumeNextToken(); if (startindex == -1) { startindex = token.startIndex; } //<semicolon-token> //<EOF-token> if (token.Type == enumTokenType.semicolon || token.Type == enumTokenType.EOF) { //Return the at-rule. rule.startindex = startindex; rule.endindex = token.endIndex; if (token.Type == enumTokenType.EOF) { rule.endindex = rule.endindex - 1; } return(rule); } //<{-token> else if (token.Type == enumTokenType.curly_bracket_left) { //Consume a simple block and assign it to the at-rule’s block. Return the at-rule. SimpleBlock simpleblock = ConsumeSimpleBlock(); simpleblock.startindex = token.startIndex; rule.block = simpleblock; rule.startindex = startindex; rule.endindex = simpleblock.endindex; return(rule); } //simple block with an associated token of <{-token> //Assign the block to the at-rule’s block. Return the at-rule. ///TODO: ???? check what does this means??? //anything else else { //Reconsume the current input token. Consume a component value. Append the returned value to the at-rule’s prelude. ReconsumeToken(); ComponentValue value = ConsumeComponentValue(); rule.prelude.Add(value); } } }
/// <summary> /// The @import at-rule is a simple statement. After its name, it takes a single string or url() function to indicate the stylesheet that it should import. /// </summary> /// <param name="rule"></param> /// <returns></returns> private static CSSRule ParseImportRule(AtRule rule, string baseurl, bool downloadImportRule, ref string OriginalCss) { /// the import starts with import atkeyword token. /// it should have been checked before calling this method, can be ignored. PreservedToken token = rule.prelude[0] as PreservedToken; int count = rule.prelude.Count; CSSImportRule importrule = new CSSImportRule(); string media = string.Empty; int startindex = -1; int endindex = -1; for (int i = 0; i < count; i++) { if (startindex < 0) { startindex = rule.prelude[i].startindex; } if (rule.prelude[i].endindex > endindex) { endindex = rule.prelude[i].endindex; } if (rule.prelude[i].Type == CompoenentValueType.preservedToken) { PreservedToken preservedToken = rule.prelude[i] as PreservedToken; /// ignore the whitespace and at-keyword token. if (preservedToken.token.Type == enumTokenType.at_keyword || (string.IsNullOrEmpty(importrule.href) && preservedToken.token.Type == enumTokenType.whitespace)) { continue; } if (string.IsNullOrEmpty(importrule.href)) { if (preservedToken.token.Type == enumTokenType.String) { string_token stringtoken = preservedToken.token as string_token; string url = string.Empty; if (string.IsNullOrEmpty(baseurl)) { url = stringtoken.value; } else { url = PathHelper.combine(baseurl, stringtoken.value); } importrule.href = url; if (downloadImportRule && !string.IsNullOrEmpty(url)) { importrule.stylesheet = CSSParser.ParseCSSStyleSheetFromUrl(url); } } else if (preservedToken.token.Type == enumTokenType.url) { url_token urltoken = preservedToken.token as url_token; string url = string.Empty; if (string.IsNullOrEmpty(baseurl)) { url = urltoken.value; } else { url = PathHelper.combine(baseurl, urltoken.value); } importrule.href = url; if (downloadImportRule && !string.IsNullOrEmpty(url)) { importrule.stylesheet = CSSParser.ParseCSSStyleSheetFromUrl(url); } } else { // must start with a string or url token as the next. string error = "this is an error"; } } else { // the import rule has href already, next is the media rules. if (preservedToken.token.Type == enumTokenType.comma || preservedToken.token.Type == enumTokenType.semicolon) { if (!string.IsNullOrEmpty(media)) { importrule.media.appendMedium(media.Trim()); media = string.Empty; } } else { // can be delim token. if (string.IsNullOrEmpty(media) && preservedToken.token.Type == enumTokenType.whitespace) { // the start of whitespace will be ignored. } else { media += preservedToken.token.GetString(ref OriginalCss); } } } } else if (rule.prelude[i].Type == CompoenentValueType.function) { Function urlfunction = rule.prelude[i] as Function; string href = string.Empty; if (urlfunction.name == "url") { foreach (var item in urlfunction.value) { if (item.Type == CompoenentValueType.preservedToken) { PreservedToken pretoken = item as PreservedToken; if (pretoken.token.Type == enumTokenType.String) { string_token stringtoken = pretoken.token as string_token; href += stringtoken.value; } } } } if (!string.IsNullOrEmpty(href)) { importrule.href = href; } } else if (rule.prelude[i].Type == CompoenentValueType.simpleBlock) { // simple block is the block like screen and (min-width:300); SimpleBlock block = rule.prelude[i] as SimpleBlock; string mediarule = string.Empty; foreach (var item in block.value) { if (item.Type == CompoenentValueType.preservedToken) { PreservedToken pretoken = item as PreservedToken; mediarule += pretoken.token.GetString(ref OriginalCss); if (token.token.endIndex > endindex) { endindex = token.token.endIndex; } } } if (block.token.Type == enumTokenType.round_bracket_left || block.token.Type == enumTokenType.round_bracket_right) { mediarule = "(" + mediarule + ")"; } else if (block.token.Type == enumTokenType.square_bracket_left || block.token.Type == enumTokenType.square_bracket_right) { mediarule = "[" + mediarule + "]"; } else if (block.token.Type == enumTokenType.curly_bracket_left || block.token.Type == enumTokenType.curly_bracket_right) { mediarule = "{" + mediarule + "}"; } media += mediarule; } } if (!string.IsNullOrEmpty(media)) { importrule.media.appendMedium(media.Trim()); media = string.Empty; } importrule.StartIndex = startindex; if (rule.endindex > endindex) { endindex = rule.endindex; } importrule.EndIndex = endindex; int endselectorindex = rule.prelude[0].endindex + 1; ///import rule does not have one extra char like { // importrule.EndSelectorIndex = endselectorindex - importrule.StartIndex + 1; importrule.EndSelectorIndex = endselectorindex - importrule.StartIndex; return(importrule); }
/// <summary> /// consume a list of cssrule from simpleblock, /// Recursive. /// </summary> /// <param name="block"></param> /// <returns></returns> private static CSSRuleList ParseMediaRuleList(SimpleBlock block, ref int endindex, CSSMediaRule parentmediarule, ref string OriginalCss) { int count = block.value.Count; CSSRuleList rulelist = new CSSRuleList(); MediaRuleParseState state = MediaRuleParseState.init; CSSStyleRule stylerule = null; CSSMediaRule mediarule = null; string media = string.Empty; string wholeconditiontext = string.Empty; int startindex = -1; for (int i = 0; i < count; i++) { if (block.value[i].endindex > endindex) { endindex = block.value[i].endindex; } if (startindex < 0) { startindex = block.value[i].startindex; } switch (state) { case MediaRuleParseState.init: { if (block.value[i].Type == CompoenentValueType.preservedToken) { PreservedToken pretoken = block.value[i] as PreservedToken; if (pretoken.token.Type == enumTokenType.whitespace) { // ignored whitespace at the beginning. } else if (pretoken.token.Type == enumTokenType.at_keyword) { // at keyword token, only handle media now. // others to be added. at_keyword_token token = pretoken.token as at_keyword_token; if (token.value.ToLower() == "media") { state = MediaRuleParseState.mediarule; i = i - 1; // reconsume to have correct startindex. } else { // other at rules. state = MediaRuleParseState.OtherAtRule; i = i - 1; } } /// else treat as regular style rule. else { state = MediaRuleParseState.stylerule; i = i - 1; // reconsume. } } break; } case MediaRuleParseState.stylerule: { if (stylerule == null) { stylerule = new CSSStyleRule(); startindex = block.value[i].startindex; } if (block.value[i].Type == CompoenentValueType.preservedToken) { PreservedToken pretoken = block.value[i] as PreservedToken; // not a defined way to parse the selector, assembly them back and give it to selector module. // in the new way of getting selectorText, we have not need to assign it any more. //stylerule.selectorText += pretoken.token.getString(); } else if (block.value[i].Type == CompoenentValueType.simpleBlock) { int endselectorindex = block.value[i].startindex; stylerule.style = ParseDeclarations(block.value[i] as SimpleBlock, ref endindex, ref OriginalCss); stylerule.StartIndex = startindex; stylerule.EndIndex = endindex; stylerule.EndSelectorIndex = endselectorindex - stylerule.StartIndex; stylerule.parentRule = parentmediarule; stylerule.parentStyleSheet = parentmediarule.parentStyleSheet; rulelist.appendRule(stylerule); stylerule = null; state = MediaRuleParseState.init; startindex = -1; } break; } case MediaRuleParseState.mediarule: { if (mediarule == null) { mediarule = new CSSMediaRule(); media = string.Empty; wholeconditiontext = string.Empty; startindex = block.value[i].startindex; mediarule.parentStyleSheet = parentmediarule.parentStyleSheet; mediarule.parentRule = parentmediarule; } if (block.value[i].Type == CompoenentValueType.preservedToken) { PreservedToken pretoken = block.value[i] as PreservedToken; if (pretoken.token.Type == enumTokenType.comma) { if (!string.IsNullOrEmpty(media)) { mediarule.media.appendMedium(media.Trim()); media = string.Empty; } wholeconditiontext += ","; } else { // can be delim token. if (string.IsNullOrEmpty(media) && pretoken.token.Type == enumTokenType.whitespace) { // the start of whitespace will be ignored. } else { media += pretoken.token.GetString(ref OriginalCss); wholeconditiontext += pretoken.token.GetString(ref OriginalCss); } } } else if (block.value[i].Type == CompoenentValueType.simpleBlock) { CSSRuleList mediarulelist = ParseMediaRuleList(block.value[i] as SimpleBlock, ref endindex, mediarule, ref OriginalCss); mediarule.cssRules = mediarulelist; if (!string.IsNullOrEmpty(media)) { mediarule.media.appendMedium(media.Trim()); wholeconditiontext += media; } mediarule.conditionText = wholeconditiontext; mediarule.selectorText = wholeconditiontext; /// NON-W3C. mediarule.StartIndex = startindex; mediarule.EndIndex = endindex; rulelist.appendRule(mediarule); state = 0; mediarule = null; media = string.Empty; wholeconditiontext = string.Empty; startindex = -1; } break; } case MediaRuleParseState.OtherAtRule: { //if (mediarule == null) //{ // mediarule = new CSSMediaRule(); // media = string.Empty; // wholeconditiontext = string.Empty; // startindex = block.value[i].startindex; // mediarule.parentStyleSheet = parentmediarule.parentStyleSheet; // mediarule.parentRule = parentmediarule; //} if (block.value[i].Type == CompoenentValueType.preservedToken) { //PreservedToken pretoken = block.value[i] as PreservedToken; //if (pretoken.token.Type == enumTokenType.comma) //{ // if (!string.IsNullOrEmpty(media)) // { // mediarule.media.appendMedium(media.Trim()); // media = string.Empty; // } // wholeconditiontext += ","; //} //else //{ // // can be delim token. // if (string.IsNullOrEmpty(media) && pretoken.token.Type == enumTokenType.whitespace) // { // // the start of whitespace will be ignored. // } // else // { // media += pretoken.token.GetString(ref OriginalCss); // wholeconditiontext += pretoken.token.GetString(ref OriginalCss); // } //} } else if (block.value[i].Type == CompoenentValueType.simpleBlock) { // not implemented now. //CSSRuleList mediarulelist = ParseMediaRuleList(block.value[i] as SimpleBlock, ref endindex, mediarule, ref OriginalCss); //mediarule.cssRules = mediarulelist; //if (!string.IsNullOrEmpty(media)) //{ // mediarule.media.appendMedium(media.Trim()); // wholeconditiontext += media; //} //mediarule.conditionText = wholeconditiontext; //mediarule.selectorText = wholeconditiontext; /// NON-W3C. //mediarule.StartIndex = startindex; //mediarule.EndIndex = endindex; //rulelist.appendRule(mediarule); state = MediaRuleParseState.init; startindex = -1; } break; } default: break; } } if (stylerule != null) { if (stylerule.EndIndex > stylerule.StartIndex) { rulelist.appendRule(stylerule); } stylerule = null; } if (mediarule != null) { rulelist.appendRule(mediarule); mediarule = null; } return(rulelist); }
/// <summary> /// Consume a list of declaration from a simple block. /// </summary> /// <param name="block"></param> /// <returns></returns> private static CSSStyleDeclaration ParseDeclarations(SimpleBlock block, ref int endindex, ref string CssText) { CSSStyleDeclaration declarations = new CSSStyleDeclaration(); string csstext = string.Empty; CSSDeclaration onedeclaration = null; bool colonfound = false; // check value before or after colon. int valuecount = block.value.Count; for (int i = 0; i < valuecount; i++) { ComponentValue item = block.value[i]; if (item.endindex > endindex) { endindex = item.endindex; } if (item.Type == CompoenentValueType.preservedToken) { PreservedToken token = item as PreservedToken; if (token.token.Type == enumTokenType.ident) { // the first ident is the start of one declaration. if (onedeclaration == null) { onedeclaration = new CSSDeclaration(); ident_token identtoken = token.token as ident_token; onedeclaration.propertyname = identtoken.value; colonfound = false; } else { onedeclaration.value += token.token.GetString(ref CssText); } } else if (token.token.Type == enumTokenType.semicolon || token.token.Type == enumTokenType.EOF) { // this is the end of one declaration. declarations.item.Add(onedeclaration); onedeclaration = null; colonfound = false; } else if (colonfound == false) { if (token.token.Type == enumTokenType.colon) { colonfound = true; } else if (token.token.Type == enumTokenType.whitespace) { // white space do nothing. } else { // the next one must be white space or colon, otherwise, error. //TODO: onError. } } else if (token.token.Type == enumTokenType.delim && ((delim_token)token.token).value == '!') { if ((i + 1) < valuecount) { if (block.value[i + 1].Type == CompoenentValueType.preservedToken) { PreservedToken important = block.value[i + 1] as PreservedToken; if (important.token.Type == enumTokenType.ident) { ident_token importantident = important.token as ident_token; if (importantident.value.ToLower() == "important" && onedeclaration != null) { onedeclaration.important = true; } } } // has to consume the important now, because value has been processed. i = i + 1; } } else { /// append the value to declaration value. if (onedeclaration != null) { onedeclaration.value += token.token.GetString(ref CssText); } } } else if (item.Type == CompoenentValueType.function) { Function func = item as Function; if (onedeclaration == null) { onedeclaration = new CSSDeclaration(); onedeclaration.propertyname = func.getString(ref CssText); colonfound = false; } else { if (colonfound) { onedeclaration.value += func.getString(ref CssText); } else { onedeclaration.propertyname += func.getString(ref CssText); } } } } if (onedeclaration != null && !string.IsNullOrEmpty(onedeclaration.propertyname)) { declarations.item.Add(onedeclaration); onedeclaration = null; colonfound = false; } if (block.endindex > endindex) { endindex = block.endindex; } return(declarations); }