public override State PushChar (char c, IParseContext context, ref string rollback) { //NOTE: This is (mostly) duplicated in HtmlTagState //handle inline tags implicitly closed by block-level elements if (context.CurrentStateLength == 1 && context.PreviousState is XmlNameState) { XClosingTag ct = (XClosingTag) context.Nodes.Peek (); if (!ct.Name.HasPrefix && ct.Name.IsValid) { //Note: the node stack will always be at least 1 deep due to the XDocument var parent = context.Nodes.Peek (1) as XElement; //if it's not a matching closing tag if (parent != null && !string.Equals (ct.Name.Name, parent.Name.Name, StringComparison.OrdinalIgnoreCase)) { //attempt to implicitly close the parents while (parent != null && parent.ValidAndNoPrefix () && parent.IsImplicitlyClosedBy (ct)) { context.Nodes.Pop (); context.Nodes.Pop (); if (warnAutoClose) { context.LogWarning (string.Format ("Tag '{0}' implicitly closed by closing tag '{1}'.", parent.Name.Name, ct.Name.Name), parent.Region); } //parent.Region.End = element.Region.Start; //parent.Region.EndColumn = Math.Max (parent.Region.EndColumn - 1, 1); parent.Close (parent); context.Nodes.Push (ct); parent = context.Nodes.Peek (1) as XElement; } } } } return base.PushChar (c, context, ref rollback); }
public override State PushChar (char c, IParseContext context, ref string rollback) { if (context.CurrentStateLength == 0) context.StateTag = 0; if (c == '<') { if (context.StateTag == 0) { context.StateTag++; return null; } } if (context.StateTag > 0) { if (CLOSE[context.StateTag] == c) { context.StateTag++; if (context.StateTag == CLOSE.Length) { var el = (XElement) context.Nodes.Pop (); var closing = new XClosingTag (new XName ("script"), context.LocationMinus (CLOSE.Length)); closing.End (context.Location); el.Close (closing); return Parent; } } else { context.StateTag = 0; } } return null; }
public override bool CanParse(IParseContext context) { var extension = Path.GetExtension(context.Snapshot.SourceFile.AbsoluteFileName).TrimStart('.').ToLowerInvariant(); var templateIdOrPath = context.Configuration.Get(Constants.Configuration.BuildProjectMediaTemplate + ":" + extension); return templateIdOrPath != null; }
public override State PushChar (char c, IParseContext context, ref string rollback) { if (context.CurrentStateLength == 1) { context.Nodes.Push (new XCData (context.LocationMinus ("<![CDATA[".Length + 1))); } if (c == ']') { //make sure we know when there are two ']' chars together if (context.StateTag == NOMATCH) context.StateTag = SINGLE_BRACKET; else context.StateTag = DOUBLE_BRACKET; } else if (c == '>' && context.StateTag == DOUBLE_BRACKET) { // if the ']]' is followed by a '>', the state has ended // so attach a node to the DOM and end the state XCData cdata = (XCData) context.Nodes.Pop (); if (context.BuildTree) { cdata.End (context.Location); ((XContainer) context.Nodes.Peek ()).AddChildNode (cdata); } return Parent; } else { // not any part of a ']]>', so make sure matching is reset context.StateTag = NOMATCH; } return null; }
public override State PushChar (char c, IParseContext context, ref string rollback) { System.Diagnostics.Debug.Assert (((XAttribute) context.Nodes.Peek ()).Value == null); if (c == '<') { //the parent state should report the error rollback = string.Empty; return Parent; } else if (c == '>' && context.KeywordBuilder.Length > 0) { string fullName = ((XAttribute) context.Nodes.Peek ()).Name.FullName; context.LogError ("The value of attribute '" + fullName + "' ended unexpectedly."); rollback = string.Empty; return Parent; } else if (char.IsLetterOrDigit (c) || c == '_' || c == '.') { context.KeywordBuilder.Append (c); return null; } else if (char.IsWhiteSpace (c) || c == '>' || c == '\\') { //ending the value XAttribute att = (XAttribute) context.Nodes.Peek (); att.Value = context.KeywordBuilder.ToString (); } else { //MalformedTagState handles error reporting //context.LogWarning ("Unexpected character '" + c + "' getting attribute value"); return MalformedTagState; } rollback = string.Empty; return Parent; }
public override State PushChar (char c, IParseContext context, ref string rollback) { System.Diagnostics.Debug.Assert (((XAttribute) context.Nodes.Peek ()).Value == null); if (c == '<') { //the parent state should report the error rollback = string.Empty; return Parent; } if (context.CurrentStateLength == 1) { if (c == '\'' || c == '"') { context.StateTag = c; return null; } context.StateTag = '\0'; } else if (context.StateTag == '\0') { return BuildUnquotedValue (c, context, ref rollback); } if (c == context.StateTag) { //ending the value var att = (XAttribute) context.Nodes.Peek (); att.Value = context.KeywordBuilder.ToString (); return Parent; } context.KeywordBuilder.Append (c); return null; }
public override State PushChar (char c, IParseContext context, ref string rollback) { if (context.CurrentStateLength == 1) { AddExpressionNode (c, context); } else if (c == '%') { context.StateTag = PERCENT; } else if (c == '>') { if (context.StateTag == PERCENT) { XNode expr = (XNode) context.Nodes.Pop (); expr.End (context.Location); if (context.BuildTree) { XObject ob = context.Nodes.Peek (); var xc = ob as XContainer; if (xc != null) { xc.AddChildNode (expr); } //FIXME: add to other kinds of node, e.g. if used within a tag } return Parent; } else { context.StateTag = NONE; } } return null; }
public override bool CanParse(IParseContext context) { var fileExtensions = " " + context.Configuration.GetString(Constants.Configuration.BuildProjectContentFiles) + " "; var extension = " " + Path.GetExtension(context.Snapshot.SourceFile.AbsoluteFileName) + " "; return fileExtensions.IndexOf(extension, StringComparison.OrdinalIgnoreCase) >= 0; }
internal static void AddExpressionNode (char c, IParseContext context) { Debug.Assert (c != '@' && c!= '-', "AspNetExpressionState should not be passed a directive or comment"); switch (c) { //DATABINDING EXPRESSION <%# case '#': context.Nodes.Push (new AspNetDataBindingExpression (context.LocationMinus (3))); break; //RESOURCE EXPRESSION <%$ case '$': context.Nodes.Push (new AspNetResourceExpression (context.LocationMinus (3))); break; //RENDER EXPRESSION <%= case '=': context.Nodes.Push (new AspNetRenderExpression (context.LocationMinus (3))); break; //HTML ENCODED EXPRESSION <%: case ':': context.Nodes.Push (new AspNetHtmlEncodedExpression (context.LocationMinus (3))); break; // RENDER BLOCK default: context.Nodes.Push (new AspNetRenderBlock (context.LocationMinus (3))); break; } }
public override State PushChar (char c, IParseContext context, ref string rollback) { if (c == '@' && context.StateTag == FREE) { context.StateTag = TRANSITION; return null; } else if (context.StateTag == TRANSITION) { rollback = String.Empty; switch (c) { case '{': // Code block @{ return CodeBlockState; case '*': // Comment @* return ServerCommentState; case '(': // Explicit expression @( return ExpressionState; default: // If char preceding @ was a letter or a digit, don't switch to expression, e.g. [email protected] if (context.CurrentStateLength <= 2 || (!Char.IsLetterOrDigit (previousChar) && (Char.IsLetter (c) || c == '_'))) // Statement, directive or implicit expression return SpeculativeState; else context.StateTag = FREE; break; } } previousChar = c; return base.PushChar (c, context, ref rollback); }
public override State PushChar (char c, IParseContext context, ref string rollback) { if (c == '<') { } return base.PushChar (c, context, ref rollback); }
static void ParseSkip(ExpressionParser parser, IParseContext sequence, ISqlExpression prevSkipValue, ISqlExpression expr) { var sql = sequence.SqlQuery; parser.SqlProvider.SqlQuery = sql; sql.Select.Skip(expr); parser.SqlProvider.SqlQuery = sql; if (sql.Select.TakeValue != null) { if (parser.SqlProvider.IsSkipSupported || !parser.SqlProvider.IsTakeSupported) sql.Select.Take(parser.Convert( sequence, new SqlBinaryExpression(typeof(int), sql.Select.TakeValue, "-", sql.Select.SkipValue, Precedence.Additive))); if (prevSkipValue != null) sql.Select.Skip(parser.Convert( sequence, new SqlBinaryExpression(typeof(int), prevSkipValue, "+", sql.Select.SkipValue, Precedence.Additive))); } if (!parser.SqlProvider.TakeAcceptsParameter) { var p = sql.Select.SkipValue as SqlParameter; if (p != null) p.IsQueryParameter = false; } }
public override State PushChar (char c, IParseContext context, ref string rollback) { if (context.CurrentStateLength == 1) { context.Nodes.Push (new XProcessingInstruction (context.LocationMinus ("<?".Length))); } if (c == '?') { if (context.StateTag == NOMATCH) { context.StateTag = QUESTION; return null; } } else if (c == '>' && context.StateTag == QUESTION) { // if the '?' is followed by a '>', the state has ended // so attach a node to the DOM and end the state XProcessingInstruction xpi = (XProcessingInstruction) context.Nodes.Pop (); if (context.BuildTree) { xpi.End (context.Location); ((XContainer) context.Nodes.Peek ()).AddChildNode (xpi); } return Parent; } else { context.StateTag = NOMATCH; } return null; }
protected override IParseContext ParseMethodCall(ExpressionParser parser, IParseContext parent, MethodCallExpression methodCall, SqlQuery sqlQuery) { var sequence = parser.ParseSequence(parent, methodCall.Arguments[0], sqlQuery); var defaultValue = methodCall.Arguments.Count == 1 ? null : methodCall.Arguments[1].Unwrap(); return new DefaultIfEmptyContext(sequence, defaultValue); }
public override bool ValidateSchema(IParseContext context) { if (string.IsNullOrEmpty(SchemaFileName) || string.IsNullOrEmpty(SchemaNamespace)) { return true; } var doc = RootElement?.Document; if (doc == null) { return true; } XmlSchemaSet schema; if (!Schemas.TryGetValue(SchemaNamespace, out schema)) { schema = GetSchema(context, SchemaFileName, SchemaNamespace); Schemas[SchemaNamespace] = schema; } if (schema == null) { return true; } var isValid = true; ValidationEventHandler validateHandler = delegate(object sender, ValidationEventArgs args) { var length = 0; var element = sender as XElement; if (element != null) { length = element.Name.LocalName.Length; } switch (args.Severity) { case XmlSeverityType.Error: context.Trace.TraceError(Msg.P1001, args.Message, SourceFile.AbsoluteFileName, new TextSpan(args.Exception.LineNumber, args.Exception.LinePosition, length)); isValid = false; break; case XmlSeverityType.Warning: context.Trace.TraceWarning(Msg.P1002, args.Message, SourceFile.AbsoluteFileName, new TextSpan(args.Exception.LineNumber, args.Exception.LinePosition, length)); break; } }; try { doc.Validate(schema, validateHandler); } catch (Exception ex) { context.Trace.TraceError(Msg.P1003, Texts.The_file_does_not_contain_valid_XML, context.Snapshot.SourceFile.AbsoluteFileName, TextSpan.Empty, ex.Message); } return isValid; }
public override bool CanParse(IParseContext context) { // todo: potential incorrect as an extension might match part of another extension var fileExtensions = context.Configuration.GetString(Constants.Configuration.MappingContentFiles); var extension = Path.GetExtension(context.Snapshot.SourceFile.AbsoluteFileName); return fileExtensions.IndexOf(extension, StringComparison.OrdinalIgnoreCase) >= 0; }
public override void Parse(IParseContext context) { var mediaFile = context.Factory.MediaFile(context.Project, context.Snapshot, context.DatabaseName, context.ItemName, context.ItemPath, context.FilePath); mediaFile.UploadMedia = context.UploadMedia; context.Project.AddOrMerge(mediaFile); context.Project.Ducats += 100; }
public override State PushChar (char c, IParseContext context, ref string rollback) { if (context.CurrentStateLength == 1) { Debug.Assert (c != '@' && c!= '-', "AspNetExpressionState should not be passed a directive or comment"); switch (c) { //DATABINDING EXPRESSION <%# case '#': context.Nodes.Push (new AspNetDataBindingExpression (context.LocationMinus (3))); break; //RESOURCE EXPRESSION <%$ case '$': context.Nodes.Push (new AspNetResourceExpression (context.LocationMinus (3))); break; //RENDER EXPRESSION <%= case '=': context.Nodes.Push (new AspNetRenderExpression (context.LocationMinus (3))); break; //HTML ENCODED EXPRESSION <%: case ':': context.Nodes.Push (new AspNetHtmlEncodedExpression (context.LocationMinus (3))); break; // RENDER BLOCK default: context.Nodes.Push (new AspNetRenderBlock (context.LocationMinus (2))); break; } return null; } else if (c == '%') { if (context.StateTag != PERCENT) context.StateTag = PERCENT; } else if (c == '>') { if (context.StateTag == PERCENT) { XNode expr = (XNode) context.Nodes.Pop (); expr.End (context.Location); if (context.BuildTree) { XObject ob = context.Nodes.Peek (); if (ob is XContainer) { ((XContainer)ob).AddChildNode (expr); } //FIXME: add to other kinds of node, e.g. if used within a tag } return Parent; } else { context.StateTag = NONE; } } return null; }
public override State PushChar (char c, IParseContext context, ref string rollback) { INamedXObject namedObject = context.Nodes.Peek () as INamedXObject; if (namedObject == null || namedObject.Name.Prefix != null) throw new InvalidOperationException ("Invalid state"); Debug.Assert (context.CurrentStateLength > 1 || char.IsLetter (c) || c == '_', "First character pushed to a XmlTagNameState must be a letter."); Debug.Assert (context.CurrentStateLength > 1 || context.KeywordBuilder.Length == 0, "Keyword builder must be empty when state begins."); if (c == ':') { if (namedObject.Name.Name != null || context.KeywordBuilder.Length == 0) { context.LogError ("Unexpected ':' in name."); return Parent; } namedObject.Name = new XName (context.KeywordBuilder.ToString ()); context.KeywordBuilder.Length = 0; return null; } if (XmlChar.IsWhitespace (c) || c == '<' || c == '>' || c == '/' || c == '=') { rollback = string.Empty; if (context.KeywordBuilder.Length == 0) { context.LogError ("Zero-length name."); } else if (namedObject.Name.Name != null) { //add prefix (and move current "name" to prefix) namedObject.Name = new XName (namedObject.Name.Name, context.KeywordBuilder.ToString ()); } else { namedObject.Name = new XName (context.KeywordBuilder.ToString ()); } //note: parent's MalformedTagState logs an error, so skip this //if (c == '<') //context.LogError ("Unexpected '<' in name."); return Parent; } if (c == ':') { if (namedObject.Name.Name != null || context.KeywordBuilder.Length == 0) { context.LogError ("Unexpected ':' in name."); return Parent; } namedObject.Name = new XName (context.KeywordBuilder.ToString ()); context.KeywordBuilder.Length = 0; return null; } if (XmlChar.IsNameChar (c)) { context.KeywordBuilder.Append (c); return null; } rollback = string.Empty; context.LogError ("Unexpected character '" + c +"'"); return Parent; }
public override State PushChar (char c, IParseContext context, ref string rollback) { // allow < in values if (context.StateTag != '\0' && context.CurrentStateLength > 1 && c == '<') { context.KeywordBuilder.Append (c); return null; } return base.PushChar (c, context, ref rollback); }
public override State PushChar (char c, IParseContext context, ref string rollback) { AspNetDirective directive = context.Nodes.Peek () as AspNetDirective; if (directive == null || directive.IsComplete) { directive = new AspNetDirective (context.LocationMinus (4)); // 4 == <%@ + current char context.Nodes.Push (directive); } if (c == '<') { context.LogError ("Unexpected '<' in directive."); rollback = string.Empty; return MalformedTagState; } Debug.Assert (!directive.IsComplete); if (context.StateTag != ENDING && c == '%') { context.StateTag = ENDING; return null; } if (context.StateTag == ENDING) { if (c == '>') { //have already checked that directive is not null, i.e. top of stack is our directive context.Nodes.Pop (); if (!directive.IsNamed) { context.LogError ("Directive closed prematurely."); } else { directive.End (context.Location); if (context.BuildTree) { XContainer container = (XContainer) context.Nodes.Peek (); container.AddChildNode (directive); } } return Parent; } //ending but not '>'? Error; go to end. } else if (char.IsLetter (c)) { rollback = string.Empty; if (!directive.IsNamed) { return NameState; } else { return AttributeState; } } else if (char.IsWhiteSpace (c)) return null; rollback = string.Empty; context.LogError ("Unexpected character '" + c + "' in tag."); return MalformedTagState; }
public override State PushChar (char c, IParseContext context, ref string rollback) { switch (context.StateTag) { case INCOMING: if (c == '<' && context.PreviousState != ExpressionState && context.PreviousState != CommentState) { context.StateTag = BRACKET; return null; } else if (context.PreviousState == ExpressionState || context.PreviousState == CommentState) { //expression has successfully been collected //we should go back to the AttributeValueState or the TagState, not the AttributeState rollback = string.Empty; return Parent is XmlAttributeState ? Parent.Parent : Parent; } break; case BRACKET: if (c == '%') { context.StateTag = PERCENT; return null; } else { context.StateTag = MALFORMED; context.LogError ("Unexpected tag start"); rollback = "<"; } break; case PERCENT: if (c == '-') { context.StateTag = PERCENT_DASH; return null; } else if (c == '@') { context.StateTag = MALFORMED; context.LogError ("Invalid directive location"); rollback = "<%"; } else { rollback = string.Empty; return ExpressionState; } break; case PERCENT_DASH: if (c == '-') { return CommentState; } else { context.StateTag = MALFORMED; context.LogError ("Malformed server comment"); rollback = "<%-"; } break; case MALFORMED: break; } return base.PushChar (c, context, ref rollback); }
protected override IParseContext ParseMethodCall(ExpressionParser parser, IParseContext parent, MethodCallExpression methodCall, SqlQuery sqlQuery) { var sequence = parser.ParseSequence(parent, methodCall.Arguments[0], sqlQuery); var condition = (LambdaExpression)methodCall.Arguments[1].Unwrap(); var result = parser.ParseWhere(sequence, condition, true); result.SetAlias(condition.Parameters[0].Name); return result; }
public override State PushChar (char c, IParseContext context, ref string rollback) { if (context.CurrentStateLength == 1) { switch (c) { case '(': context.StateTag = NONE_EXPLICIT; context.Nodes.Push (new RazorExplicitExpression (context.LocationMinus (2))); return null; default: context.StateTag = NONE_IMPLICIT; if (!(context.PreviousState is RazorSpeculativeState)) context.Nodes.Push (new RazorImplicitExpression (context.LocationMinus (2))); break; } } switch (c) { case '(': if (context.StateTag == NONE_EXPLICIT) context.StateTag = INSIDE_BRACKET_EXPLICIT; else if (context.StateTag == NONE_IMPLICIT) context.StateTag = INSIDE_BRACKET_IMPLICIT; context.KeywordBuilder.Append (c); break; case ')': if (context.StateTag == NONE_EXPLICIT) { StateEngineService.EndCodeFragment<RazorExplicitExpression> (context); return Parent; } else if (context.StateTag != NONE_IMPLICIT) { if (context.KeywordBuilder.Length > 0) context.KeywordBuilder.Remove (0, 1); if (context.KeywordBuilder.Length == 0) context.StateTag = (context.StateTag == INSIDE_BRACKET_IMPLICIT ? NONE_IMPLICIT : NONE_EXPLICIT); } break; default: // Space between function's name and open bracket not allowed in razor, e.g. @Html.Raw (foo) if (!(Char.IsLetterOrDigit (c) || allowedChars.Any (ch => ch == c)) && context.StateTag == NONE_IMPLICIT) { StateEngineService.EndCodeFragment<RazorImplicitExpression> (context, 1); rollback = String.Empty; if (Parent is RazorSpeculativeState) return Parent.Parent; return Parent; } break; } return null; }
public override State PushChar (char c, IParseContext context, ref string rollback) { if (context.CurrentStateLength == 0 && context.PreviousState is HtmlScriptBodyState) return Parent; //NOTE: This is (mostly) duplicated in HtmlClosingTagState //handle "paragraph" tags implicitly closed by block-level elements if (context.CurrentStateLength == 1 && context.PreviousState is XmlNameState) { XElement element = (XElement) context.Nodes.Peek (); //Note: the node stack will always be at least 1 deep due to the XDocument XElement parent = context.Nodes.Peek (1) as XElement; while (parent != null && parent.Name.IsValid && !parent.Name.HasPrefix && !element.Name.HasPrefix && element.Name.IsValid && !ElementTypes.IsInline (element.Name.Name) && (ElementTypes.IsInline (parent.Name.Name) || ElementTypes.IsParagraph (parent.Name.Name)) ) { context.Nodes.Pop (); context.Nodes.Pop (); if (warnAutoClose) { context.LogWarning (string.Format ("Tag '{0}' implicitly closed by tag '{1}'.", parent.Name.Name, element.Name.Name), parent.Region); } //parent.Region.End = element.Region.Start; //parent.Region.End.Column = Math.Max (parent.Region.End.Column - 1, 1); parent.Close (parent); context.Nodes.Push (element); parent = context.Nodes.Peek (1) as XElement; } } State ret = base.PushChar (c, context, ref rollback); if (ret == Parent && c == '>') { var element = context.Nodes.Peek () as XElement; if (element != null && !element.Name.HasPrefix && element.Name.IsValid) { if (element.Name.Name.Equals ("script", StringComparison.OrdinalIgnoreCase)) { return ScriptState; } else if (ElementTypes.IsEmpty (element.Name.Name)) { element.Close (element); context.Nodes.Pop (); if (warnAutoClose) { context.LogWarning (string.Format ("Implicitly closed empty tag '{0}'", element.Name.Name), element.Region); } } } } return ret; }
public override State PushChar (char c, IParseContext context, ref string rollback) { INamedXObject namedObject = context.Nodes.Peek () as INamedXObject; if (namedObject == null || namedObject.Name.Prefix != null) throw new InvalidOperationException ("Invalid state"); Debug.Assert (context.CurrentStateLength > 1 || char.IsLetter (c) || c == '_', "First character pushed to a XmlTagNameState must be a letter."); Debug.Assert (context.CurrentStateLength > 1 || context.KeywordBuilder.Length == 0, "Keyword builder must be empty when state begins."); if (c == ':') { if (namedObject.Name.Name != null || context.KeywordBuilder.Length == 0) { context.LogError ("Unexpected ':' in name."); return Parent; } namedObject.Name = new XName (context.KeywordBuilder.ToString ()); context.KeywordBuilder.Length = 0; return null; } if (XmlChar.IsWhitespace (c) || c == '<' || c == '>' || c == '/' || c == '=') { rollback = string.Empty; if (context.KeywordBuilder.Length == 0) { context.LogError ("Zero-length name."); } else { string s = context.KeywordBuilder.ToString (); int i = s.IndexOf (':'); if (i < 0) { namedObject.Name = new XName (s); } else { namedObject.Name = new XName (s.Substring (0, i), s.Substring (i + 1)); } } return Parent; } if (c == ':') { if (namedObject.Name.Name != null || context.KeywordBuilder.ToString ().IndexOf (':') <= 0) { context.LogError ("Unexpected ':' in name."); return Parent; } return null; } if (XmlChar.IsNameChar (c)) { context.KeywordBuilder.Append (c); return null; } rollback = string.Empty; context.LogError ("Unexpected character '" + c +"' in name"); return Parent; }
protected override IParseContext ParseMethodCall(ExpressionParser parser, IParseContext parent, MethodCallExpression methodCall, SqlQuery sqlQuery) { var sequence = parser.ParseSequence(parent, methodCall.Arguments[0], sqlQuery); var sql = sequence.SqlQuery; if (sql.Select.TakeValue != null || sql.Select.SkipValue != null) sequence = new SubQueryContext(sequence); sequence.SqlQuery.Select.IsDistinct = true; return sequence; }
public override void Parse(IParseContext context) { var rendering = context.Factory.Rendering(context.Project, context.Snapshot, context.DatabaseName, context.ItemPath, context.ItemName, context.FilePath, TemplateIdOrPath); context.Project.AddOrMerge(rendering); var contents = context.Snapshot.SourceFile.ReadAsText(); var placeholders = GetPlaceholders(contents); rendering.Placeholders.AddRange(placeholders); context.Project.Ducats += 100; }
public override State PushChar (char c, IParseContext context, ref string rollback) { string key; switch (context.StateTag) { case UNKNOWN: context.KeywordBuilder.Append (c); key = context.KeywordBuilder.ToString (); if (!RazorSymbols.CanBeStatementOrDirective (key)) { context.Nodes.Push (new RazorImplicitExpression (context.LocationMinus (key.Length + 1))); rollback = String.Empty; return EnsureSetAndAdopted<RazorExpressionState> (ref expressionState); } if (key == "using") context.StateTag = USING; else if (RazorSymbols.IsDirective (key)) context.StateTag = POSSIBLE_DIRECTIVE; else if (RazorSymbols.IsStatement (key)) context.StateTag = POSSIBLE_STATEMENT; break; // Using can be either statement: @using (resource) {}, or directive: @using System.IO case USING: if (c == '(' || c == '\n') return SwitchToStatement (context, ref rollback); else if (Char.IsLetterOrDigit(c)) return SwitchToDirective (context, ref rollback); context.KeywordBuilder.Append (c); break; case POSSIBLE_STATEMENT: if (Char.IsWhiteSpace (c) || c == '{' || c == '(') return SwitchToStatement(context, ref rollback); context.KeywordBuilder.Append (c); context.StateTag = UNKNOWN; break; case POSSIBLE_DIRECTIVE: if (Char.IsWhiteSpace (c) || c == '{') return SwitchToDirective (context, ref rollback); context.KeywordBuilder.Append (c); context.StateTag = UNKNOWN; break; } return null; }
public override bool CanParse(IParseContext context) { var fileName = context.Snapshot.SourceFile.AbsoluteFileName; if (fileName.EndsWith(ConfigFileExtension, StringComparison.OrdinalIgnoreCase)) { return true; } if (fileName.EndsWith(DisabledConfigFileExtension, StringComparison.OrdinalIgnoreCase)) { return true; } return fileName.EndsWith(ExampleConfigFileExtension, StringComparison.OrdinalIgnoreCase); }
public string Parse(string html, IParseContext context) { return(StlParserManager.ParseInnerContent(html, (ParseContextImpl)context)); }
public string ParseInnerXml(string innerXml, IParseContext context) { return(StlParserManager.ParseInnerContent(innerXml, context)); }
protected virtual void Init(CallableElement callableElement, IParseContext context, XElement element) { callableElement.Name = element.GetAttribute("name"); base.Init(callableElement, context, element); }
protected abstract IParseContext ParseMethodCall(ExpressionParser parser, IParseContext parent, MethodCallExpression methodCall, SqlQuery sqlQuery);
public override State PushChar(char c, IParseContext context, ref string rollback) { if (context.CurrentStateLength == 1) { bracketsBuilder.Clear(); var stm = context.Nodes.FirstOrDefault(n => n is RazorStatement); if (stm == null) { if (context.PreviousState is XmlClosingTagState && CorrespondingStatement != null) { context.Nodes.Push(CorrespondingStatement); } else { Debug.Fail("Statement should be pushed before changing the state to StatementState"); return(Parent); } } else { CorrespondingBlock = stm as RazorCodeFragment; } } if (context.StateTag == POSSIBLE_CONTINUATION) { if (!Char.IsWhiteSpace(c)) { context.KeywordBuilder.Append(c); } string currentKey = context.KeywordBuilder.ToString(); if (!keys.Any(s => s.StartsWith(currentKey))) { rollback = String.Empty; var p = Parent; while (!(p is RazorSpeculativeState)) { p = p.Parent; } return(p.Parent); } if (keys.Any(s => s == currentKey)) { if (currentKey != "else") { return(SwitchToContinuationStatement(context, currentKey)); } else { context.StateTag = ELSE; } } return(null); } if (context.StateTag == ELSE) { if (c != ' ') { string currentKey = context.KeywordBuilder.ToString(); if (c == 'i' && currentKey.Trim() == "else") { currentKey = "else if"; } return(SwitchToContinuationStatement(context, currentKey)); } context.KeywordBuilder.Append(c); return(null); } switch (c) { case '{': if (context.StateTag != TRANSITION) { return(ParseOpeningBracket(c, context)); } break; case '}': return(ParseClosingBracket <RazorStatement> (c, context, Parent.Parent)); } return(base.PushChar(c, context, ref rollback)); }
public virtual bool ValidateSchema(IParseContext context) => true;
public override void Parse(IParseContext context) { var contentFile = Factory.ContentFile(context.Project, context.Snapshot, context.FilePath); context.Project.AddOrMerge(contentFile); }
public override State PushChar(char c, IParseContext context, ref string rollback) { string key; switch (context.StateTag) { case UNKNOWN: context.KeywordBuilder.Append(c); key = context.KeywordBuilder.ToString(); if (!RazorSymbols.CanBeStatementOrDirective(key)) { context.Nodes.Push(new RazorImplicitExpression(context.LocationMinus(key.Length + 1))); rollback = String.Empty; return(EnsureSetAndAdopted <RazorExpressionState> (ref expressionState)); } if (key == "using") { context.StateTag = USING; } else if (RazorSymbols.IsDirective(key)) { context.StateTag = POSSIBLE_DIRECTIVE; } else if (RazorSymbols.IsStatement(key)) { context.StateTag = POSSIBLE_STATEMENT; } break; // Using can be either statement: @using (resource) {}, or directive: @using System.IO case USING: if (c == '(' || c == '\n') { return(SwitchToStatement(context, ref rollback)); } else if (Char.IsLetterOrDigit(c)) { return(SwitchToDirective(context, ref rollback)); } context.KeywordBuilder.Append(c); break; case POSSIBLE_STATEMENT: if (Char.IsWhiteSpace(c) || c == '{' || c == '(') { return(SwitchToStatement(context, ref rollback)); } context.KeywordBuilder.Append(c); context.StateTag = UNKNOWN; break; case POSSIBLE_DIRECTIVE: if (Char.IsWhiteSpace(c) || c == '{') { return(SwitchToDirective(context, ref rollback)); } context.KeywordBuilder.Append(c); context.StateTag = UNKNOWN; break; } return(null); }
//public static object ApiPayGet(IRequest context) //{ // var siteId = context.GetPostInt("siteId"); // var sessionId = context.GetPostString("sessionId"); // if (context.IsUserLoggin) // { // CartRepository.UpdateUserName(siteId, sessionId, context.UserName); // } // var addressInfoList = AddressDao.GetAddressInfoList(context.UserName, sessionId); // var cartInfoList = CartRepository.GetCartInfoList(siteId, context.UserName, sessionId); // AddressInfo addressInfo = null; // foreach (var addInfo in addressInfoList) // { // if (addInfo.IsDefault) addressInfo = addInfo; // } // if (addressInfo == null && addressInfoList.Count > 0) // { // addressInfo = addressInfoList[0]; // } // var deliveryInfoList = DeliveryRepository.GetDeliveryInfoList(siteId); // DeliveryInfo deliveryInfo = null; // if (deliveryInfoList.Count > 0) // { // deliveryInfo = deliveryInfoList[0]; // } // var totalCount = 0; // decimal totalFee = 0; // var deliveryFee = Utils.GetDeliveryFee(cartInfoList, addressInfo, deliveryInfo); // foreach (var cartInfo in cartInfoList) // { // totalCount += cartInfo.Count; // totalFee += cartInfo.Fee * cartInfo.Count; // } // return new // { // addressInfoList, // addressId = addressInfo?.Id ?? 0, // deliveryInfoList, // deliveryId = deliveryInfo?.Id ?? 0, // cartInfoList, // totalCount, // totalFee, // deliveryFee // }; //} //public static object ApiPaySaveAddress(IRequest context) //{ // var siteId = context.GetPostInt("siteId"); // var sessionId = context.GetPostString("sessionId"); // var deliveryId = context.GetPostInt("deliveryId"); // var addressInfo = context.GetPostObject<AddressInfo>("addressInfo"); // var isEdit = context.GetPostBool("isEdit"); // addressInfo.UserName = context.UserName; // addressInfo.SessionId = sessionId; // if (isEdit) // { // AddressDao.Update(addressInfo); // } // else // { // addressInfo.Id = AddressDao.Insert(addressInfo); // } // AddressDao.SetDefault(context.UserName, sessionId, addressInfo.Id); // var cartInfoList = CartRepository.GetCartInfoList(siteId, context.UserName, sessionId); // var deliveryInfo = DeliveryRepository.GetDeliveryInfo(deliveryId); // var deliveryFee = Utils.GetDeliveryFee(cartInfoList, addressInfo, deliveryInfo); // return new // { // addressInfo, // deliveryFee // }; //} //public static object ApiPayRemoveAddress(IRequest context) //{ // var addressId = context.GetPostInt("addressId"); // AddressDao.Delete(addressId); // return new {}; //} //public static object ApiPaySetAddressAndDelivery(IRequest context) //{ // var siteId = context.GetPostInt("siteId"); // var sessionId = context.GetPostString("sessionId"); // var addressId = context.GetPostInt("addressId"); // var deliveryId = context.GetPostInt("deliveryId"); // AddressDao.SetDefault(context.UserName, sessionId, addressId); // var cartInfoList = CartRepository.GetCartInfoList(siteId, context.UserName, sessionId); // var addressInfo = AddressDao.GetAddressInfo(addressId); // var deliveryInfo = DeliveryRepository.GetDeliveryInfo(deliveryId); // var deliveryFee = Utils.GetDeliveryFee(cartInfoList, addressInfo, deliveryInfo); // return new // { // deliveryFee // }; //} //public static object ApiPay(IRequest context) //{ // var siteId = context.GetPostInt("siteId"); // var sessionId = context.GetPostString("sessionId"); // var addressId = context.GetPostInt("addressId"); // var channel = context.GetPostString("channel"); // var totalFee = context.GetPostDecimal("totalFee"); // var deliveryFee = context.GetPostDecimal("deliveryFee"); // var totalCount = context.GetPostInt("totalCount"); // var message = context.GetPostString("message"); // var cartIdList = context.GetPostObject<List<string>>("cartIdList").Select(cartId => Utils.ParseInt(cartId)).ToList(); // var isMobile = context.GetPostBool("isMobile"); // var successUrl = context.GetPostString("successUrl"); // if (string.IsNullOrEmpty(successUrl)) // { // successUrl = Context.SiteApi.GetSiteUrl(siteId); // } // var guid = Regex.Replace(Convert.ToBase64String(Guid.NewGuid().ToByteArray()), "[/+=]", ""); // var paymentApi = new PaymentApi(siteId); // var siteInfo = Context.SiteApi.GetSiteInfo(siteId); // var addressInfo = AddressDao.GetAddressInfo(addressId); // var orderInfo = new OrderInfo // { // SiteId = siteId, // Guid = guid, // AddDate = DateTime.Now, // Address = addressInfo.Address, // ZipCode = addressInfo.ZipCode, // Location = addressInfo.Location, // Message = message, // Mobile = addressInfo.Mobile, // Channel = channel, // TotalFee = totalFee, // ExpressCost = deliveryFee, // RealName = addressInfo.RealName, // UserName = context.UserName, // SessionId = sessionId, // IsPayed = false, // State = string.Empty, // Tel = addressInfo.Tel, // TotalCount = totalCount // }; // orderInfo.Id = OrderRepository.Insert(orderInfo); // var cartInfoList = CartRepository.GetCartInfoList(siteId, context.UserName, sessionId); // var newCardIdList = new List<int>(); // foreach (var newCardInfo in cartInfoList) // { // newCardIdList.Add(newCardInfo.Id); // } // //CartDao.UpdateOrderId(cartIdList, orderInfo.Id); // CartRepository.UpdateOrderId(newCardIdList, orderInfo.Id); // var amount = totalFee + deliveryFee; // var orderNo = guid; // successUrl = $"{successUrl}?guid={guid}"; // if (channel == "alipay") // { // return isMobile // ? paymentApi.ChargeByAlipayMobi(siteInfo.SiteName, amount, orderNo, successUrl) // : paymentApi.ChargeByAlipayPc(siteInfo.SiteName, amount, orderNo, successUrl); // } // if (channel == "weixin") // { // var apiUrl = Context.PluginApi.GetPluginApiUrl(Main.PluginId); // var notifyUrl = $"{apiUrl}/{nameof(ApiPayWeixinNotify)}/{orderNo}"; // var url = HttpUtility.UrlEncode(paymentApi.ChargeByWeixin(siteInfo.SiteName, amount, orderNo, notifyUrl)); // var qrCodeUrl = // $"{apiUrl}/{nameof(ApiPayQrCode)}?qrcode={url}"; // return new // { // qrCodeUrl, // orderNo // }; // } // if (channel == "jdpay") // { // return paymentApi.ChargeByJdpay(siteInfo.SiteName, amount, orderNo, successUrl); // } // return new // { // guid, // amount // }; //} //public static HttpResponseMessage ApiPayQrCode(IRequest context) //{ // var response = new HttpResponseMessage(); // var qrcode = context.GetQueryString("qrcode"); // var qrCodeEncoder = new QRCodeEncoder // { // QRCodeEncodeMode = QRCodeEncoder.ENCODE_MODE.BYTE, // QRCodeErrorCorrect = QRCodeEncoder.ERROR_CORRECTION.M, // QRCodeVersion = 0, // QRCodeScale = 4 // }; // //将字符串生成二维码图片 // var image = qrCodeEncoder.Encode(qrcode, Encoding.Default); // //保存为PNG到内存流 // var ms = new MemoryStream(); // image.Save(ms, ImageFormat.Png); // response.Content = new ByteArrayContent(ms.GetBuffer()); // response.Content.Headers.ContentType = new MediaTypeHeaderValue("image/png"); // response.StatusCode = HttpStatusCode.OK; // return response; //} //public static HttpResponseMessage ApiPayWeixinNotify(IRequest context, string orderNo) //{ // var response = new HttpResponseMessage(); // var paymentApi = new PaymentApi(context.GetQueryInt("siteId")); // bool isPayed; // string responseXml; // paymentApi.NotifyByWeixin(HttpContext.Current.Request, out isPayed, out responseXml); // if (isPayed) // { // OrderRepository.UpdateIsPayed(orderNo); // } // response.Content = new StringContent(responseXml); // response.Content.Headers.ContentType = new MediaTypeHeaderValue("application/xml"); // response.StatusCode = HttpStatusCode.OK; // return response; //} //public static object ApiPayWeixinInterval(IRequest context) //{ // var orderNo = context.GetPostString("orderNo"); // var isPayed = OrderRepository.IsPayed(orderNo); // return new // { // isPayed // }; //} public static string Parse(IParseContext context) { var successUrl = string.Empty; var weixinName = string.Empty; foreach (var attriName in context.StlAttributes.AllKeys) { var value = context.StlAttributes[attriName]; if (Utils.EqualsIgnoreCase(attriName, AttributeSuccessUrl)) { successUrl = Context.ParseApi.ParseAttributeValue(value, context); } else if (Utils.EqualsIgnoreCase(attriName, AttributeWeixinName)) { weixinName = Context.ParseApi.ParseAttributeValue(value, context); } } var elementId = "el-" + Guid.NewGuid(); var vueId = "v" + Guid.NewGuid().ToString().Replace("-", string.Empty); var pluginUrl = Context.PluginApi.GetPluginUrl(Main.PluginId); var apiUrl = Context.Environment.ApiUrl; var jqueryUrl = $"{pluginUrl}/assets/js/jquery.min.js"; var utilsUrl = $"{pluginUrl}/assets/js/utils.js"; var vueUrl = $"{pluginUrl}/assets/js/vue.min.js"; var deviceUrl = $"{pluginUrl}/assets/js/device.min.js"; var baseCssUrl = $"{pluginUrl}/assets/css/base.css"; var locationCssUrl = $"{pluginUrl}/assets/css/location.css"; var locationJsUrl = $"{pluginUrl}/assets/js/location.js"; var apiGetUrl = $"{apiUrl}/{Main.PluginId}/ApiPayGet"; var apiSaveAddressUrl = $"{apiUrl}/{Main.PluginId}/ApiPaySaveAddress"; var apiRemoveAddressUrl = $"{apiUrl}/{Main.PluginId}/ApiPayRemoveAddress"; var apiSetAddressAndDelivery = $"{apiUrl}/{Main.PluginId}/ApiPaySetAddressAndDelivery"; var apiPayUrl = $"{apiUrl}/{Main.PluginId}/ApiPay"; var apiWeixinIntervalUrl = $"{apiUrl}/{Main.PluginId}/ApiPayWeixinInterval"; var paymentApi = new PaymentApi(context.SiteId); string template; if (!string.IsNullOrEmpty(context.StlInnerHtml)) { template = Context.ParseApi.Parse(context.StlInnerHtml, context); } else { template = @" <div class=""w1060""> <div class=""orderinfo g_orderinfo""> <div class=""g_order_mid""> <h2>收货信息</h2> <div class=""g_order_more""> <span class=""g_o_more"" @click=""isAddressList = true"">更多收货信息>></span> <span class=""g_o_add"" @click=""addAddress()""><b>新增收货地址</b><i>+</i></span> </div> <div class=""clear""></div> <ul class=""g_order_ul get_order""> <li v-for=""addressInfo in addressInfoList"" :class=""{ cut: addressInfo.id == addressId }"" @click=""setAddress(addressInfo)""> <div class=""g_o_title""> <span class=""g_o_name"">{{ addressInfo.realName }}</span> <span class=""g_o_tel"">{{ addressInfo.mobile || addressInfo.tel }}</span> </div> <div class=""g_o_address""> {{ addressInfo.location + ' ' + addressInfo.address }} </div> </li> </ul> <div class=""g_o_way"" v-show=""deliveryInfoList && deliveryInfoList.length > 1""> 运送方式: <select v-model=""deliveryId"" @change=""setAddressAndDelivery""> <option v-for=""deliveryInfo in deliveryInfoList"" v-bind:value=""deliveryInfo.id"">{{ deliveryInfo.deliveryName }}</option> </select> </div> </div> <div class=""order_h2 g_order""> 商品清单 </div> <div class=""orderinfo_div""> <ul class=""cart_ul""> <li v-for=""cartInfo in cartInfoList""> <a :href=""cartInfo.linkUrl"" class=""img_h2"" target=""_blank""> <img :src=""cartInfo.imageUrl"" /> <h2>{{ cartInfo.productName }}</h2> </a> <span class=""cart_price"">¥{{ cartInfo.fee.toFixed(2) }}</span> <div class=""cart_number""> <div class=""cart_num_text"">x<span>{{ cartInfo.count }}</span></div> </div> </li> </ul> <div class=""orderinfo_pay""> <span>共{{ totalCount }}个商品</span> <span>商品金额:¥{{ totalFee.toFixed(2) }}元</span> <span>运费:¥{{ deliveryFee.toFixed(2) }}元</span> <span class=""g_o_color"">合计:<b>¥{{ (totalFee + deliveryFee).toFixed(2) }}元</b></span> <div class=""clear""></div> </div> </div> <div class=""pay_list g_o_pay""> <p>支付方式</p> <ul> <li v-show=""(isAlipayPc && !isMobile) || (isAlipayMobi && isMobile)"" :class=""{ pay_cut: channel === 'alipay' }"" @click=""channel = 'alipay'"" class=""channel_alipay""><b></b></li> <li v-show=""isWeixin"" :class=""{ pay_cut: channel === 'weixin' }"" @click=""channel = 'weixin'"" class=""channel_weixin""><b></b></li> <li v-show=""isJdpay"" :class=""{ pay_cut: channel === 'jdpay' }"" @click=""channel = 'jdpay'"" class=""channel_jdpay""><b></b></li> </ul> </div> <div class=""order_other""> <h2>其他</h2> <div class=""g_o_text""> <textarea placeholder=""如需其他问题请留言"" v-model=""message""></textarea> </div> </div> <div class=""get_order_btn""> <div class=""get_o_pay"">应付金额:<b>¥{{ (totalFee + deliveryFee).toFixed(2) }}元</b></div> <a href=""javascript:;"" @click=""pay"" class=""g_o_btn"" :class=""{ 'g_o_btn_disabled': !this.addressId || !this.channel || !this.totalFee || !this.totalCount }"">去结算</a> </div> </div> </div> <div class=""address_mask"" style=""display: none"" v-show=""isAddressAdd || isAddressList"" @click=""isAddressAdd = isAddressList = false""></div> <div class=""address_lists"" v-show=""isAddressList""> <div class=""address_title"">收货地址</div> <div class=""address_close add_close1"" @click=""isAddressList = false""></div> <ul class=""g_order_ul address_ul""> <li v-for=""addressInfo in addressInfoList"" :class=""{ cut: addressInfo.id == addressId }"" @click=""setAddress(addressInfo)""> <div class=""g_o_title""> <span class=""g_o_name"">{{ addressInfo.realName }}</span> <span class=""g_o_tel"">{{ addressInfo.mobile || addressInfo.tel }}</span> </div> <div class=""g_o_address""> {{ addressInfo.location + ' ' + addressInfo.address }} </div> <div class=""add_del"" @click=""removeAddress(addressInfo)"">删除</div> <div class=""eidt"" @click=""editAddress(addressInfo)"">编辑</div> </li> </ul> </div> <div class=""add_cont"" v-show=""isAddressAdd""> <div class=""address_title"">收货地址</div> <div class=""address_close add_close"" @click=""isAddressAdd = false""></div> <ul class=""add_ul""> <li><span>收货人</span><input type=""text"" v-model=""addressInfo.realName"" /></li> <li class=""fleft""><span>手机号码</span><input type=""text"" v-model=""addressInfo.mobile"" /></li> <li class=""fright""><span>固定电话</span><input type=""text"" v-model=""addressInfo.tel"" /></li> <li><span>所在地区</span> <ul id=""list1""> <li id=""summary-stock""> <div class=""dd""> <div id=""store-selector""> <div class=""text""> <div>{{ addressInfo.location }}</div><b></b> </div> <div onclick=""$('#store-selector').removeClass('hover');event.stopPropagation();"" class=""close""></div> </div> <div id=""store-prompt""><strong></strong></div> </div> </li> </ul> </li> <li class=""add_ul_input""><span>详细地址</span><input type=""text"" v-model=""addressInfo.address"" /></li> <li><span>邮编</span><input type=""text"" v-model=""addressInfo.zipCode"" /></li> </ul> <a href=""javascript:;"" @click=""saveAddress(addressInfo)"" class=""add_save"">保存并提交</a> </div> "; if (!string.IsNullOrEmpty(weixinName)) { weixinName = $@"<p style=""text-align: center"">{weixinName}</p>"; } template += $@" <div class=""mask1_bg mask1_bg_cut"" v-show=""isWxQrCode"" @click=""isWxQrCode = false""></div> <div class=""detail_alert detail_alert_cut"" v-show=""isWxQrCode""> <div class=""close"" @click=""isWxQrCode = false""></div> <div class=""pay_list""> <p style=""text-align: center"">打开手机微信,扫一扫下面的二维码,即可完成支付</p> {weixinName} <p style=""margin-left: 195px;margin-bottom: 80px;""><img :src=""qrCodeUrl"" style=""width: 200px;height: 200px;""></p> </div> </div> "; } return($@" <script type=""text/javascript"" src=""{jqueryUrl}""></script> <script type=""text/javascript"" src=""{utilsUrl}""></script> <script type=""text/javascript"" src=""{vueUrl}""></script> <script type=""text/javascript"" src=""{deviceUrl}""></script> <link rel=""stylesheet"" type=""text/css"" href=""{baseCssUrl}"" /> <link rel=""stylesheet"" type=""text/css"" href=""{locationCssUrl}"" /> <div id=""{elementId}""> {template} </div> <script type=""text/javascript""> var sessionId = shoppingGetSessionId(); var {vueId} = new Vue({{ el: '#{elementId}', data: {{ addressInfoList: [], addressId: 0, deliveryInfoList: [], deliveryId: 0, cartInfoList: [], totalCount: 0, totalFee: 0, deliveryFee: 0, isAddressAdd: false, isAddressList: false, addressInfo: {{}}, message: '', channel: 'alipay', isAlipay: {paymentApi.IsAliPay.ToString().ToLower()}, isWeixin: {paymentApi.IsWxPay.ToString().ToLower()}, isMobile: device.mobile(), isWxQrCode: false, qrCodeUrl: '' }}, methods: {{ saveAddress: function (addressInfo) {{ var $this = this; var isEdit = addressInfo.id && addressInfo.id > 0 addressInfo.location = $(""#store-selector .text div"").html(); this.isAddressAdd = false; $.ajax({{ url : ""{apiSaveAddressUrl}"", xhrFields: {{ withCredentials: true }}, type: ""POST"", data: JSON.stringify({{ siteId: {context.SiteId}, sessionId: sessionId, deliveryId: $this.deliveryId, addressInfo: addressInfo, isEdit: isEdit }}), contentType: ""application/json; charset=utf-8"", dataType: ""json"", success: function(data) {{ $this.deliveryFee = data.deliveryFee; $this.addressId = data.addressInfo.id; if (!isEdit) {{ $this.addressInfoList.push(data.addressInfo); return; }} for(var i = 0; i < $this.addressInfoList.length; i++) {{ var a = $this.addressInfoList[i]; if (a.id === data.id) {{ a = data; }} }} }}, error: function (err) {{ var err = JSON.parse(err.responseText); console.log(err.message); }} }}); }}, setAddress: function (addressInfo) {{ this.addressId = addressInfo.id; this.isAddressList = false; this.setAddressAndDelivery(); }}, addAddress: function () {{ this.addressInfo = {{}}; this.isAddressAdd = true; }}, editAddress: function (addressInfo) {{ this.addressInfo = addressInfo; this.isAddressAdd = true; }}, removeAddress: function (addressInfo) {{ var index = this.addressInfoList.indexOf(addressInfo); if (index > -1) {{ this.addressInfoList.splice(index, 1); $.ajax({{ url : ""{apiRemoveAddressUrl}"", xhrFields: {{ withCredentials: true }}, type: ""POST"", data: JSON.stringify({{ siteId: '{context.SiteId}', addressId: addressInfo.id }}), contentType: ""application/json; charset=utf-8"", dataType: ""json"", success: function(data) {{ console.log('removed'); }}, error: function (err) {{ var err = JSON.parse(err.responseText); console.log(err.message); }} }}); }} }}, setAddressAndDelivery: function () {{ var $this = this; $.ajax({{ url : ""{apiSetAddressAndDelivery}"", xhrFields: {{ withCredentials: true }}, type: ""POST"", data: JSON.stringify({{ siteId: '{context.SiteId}', sessionId: sessionId, addressId: this.addressId, deliveryId: this.deliveryId }}), contentType: ""application/json; charset=utf-8"", dataType: ""json"", success: function(data) {{ $this.deliveryFee = data.deliveryFee; }}, error: function (err) {{ var err = JSON.parse(err.responseText); console.log(err.message); }} }}); }}, weixinInterval: function(orderNo) {{ var $this = this; var interval = setInterval(function(){{ $.ajax({{ url : ""{apiWeixinIntervalUrl}"", xhrFields: {{ withCredentials: true }}, type: ""POST"", data: JSON.stringify({{orderNo: orderNo}}), contentType: ""application/json; charset=utf-8"", dataType: ""json"", success: function(data) {{ if (data.isPayed) {{ location.href = '{successUrl}?guid=' + orderNo; }} }}, error: function (err) {{ var err = JSON.parse(err.responseText); console.log(err.message); }} }}); }}, 3000); }}, pay: function () {{ var cartIdList = []; for(var i = 0; i < this.cartInfoList.length; i++) {{ cartIdList.push(this.cartInfoList[i].id); }} if (cartIdList.length === 0 || !this.addressId || !this.channel || !this.totalFee || !this.totalCount) return; var $this = this; $.ajax({{ url : ""{apiPayUrl}"", xhrFields: {{ withCredentials: true }}, type: ""POST"", data: JSON.stringify({{ siteId: {context.SiteId}, sessionId: sessionId, addressId: this.addressId, channel: this.channel, totalFee: this.totalFee, deliveryFee: this.deliveryFee, totalCount: this.totalCount, message: this.message, isMobile: this.isMobile, cartIdList: cartIdList, successUrl: '{successUrl}' }}), contentType: ""application/json; charset=utf-8"", dataType: ""json"", success: function(charge) {{ if ($this.channel === 'weixin') {{ $this.isWxQrCode = true; $this.qrCodeUrl = charge.qrCodeUrl; $this.weixinInterval(charge.orderNo); }} else {{ document.write(charge); }} }}, error: function (err) {{ var err = JSON.parse(err.responseText); console.log(err.message); }} }}); }}, }} }}); $(document).ready(function(){{ $.ajax({{ url : ""{apiGetUrl}"", xhrFields: {{ withCredentials: true }}, type: ""POST"", data: JSON.stringify({{ siteId: '{context.SiteId}', sessionId: sessionId }}), contentType: ""application/json; charset=utf-8"", dataType: ""json"", success: function(data) {{ {vueId}.addressInfoList = data.addressInfoList; {vueId}.addressId = data.addressId; {vueId}.deliveryInfoList = data.deliveryInfoList; {vueId}.deliveryId = data.deliveryId; {vueId}.cartInfoList = data.cartInfoList; {vueId}.totalCount = data.totalCount; {vueId}.totalFee = data.totalFee; {vueId}.deliveryFee = data.deliveryFee; }}, error: function (err) {{ var err = JSON.parse(err.responseText); console.log(err.message); }} }}); }}); </script> <script type=""text/javascript"" charset=""utf-8"" src=""{locationJsUrl}""></script> "); }
protected override ITextNode GetItemNameTextNode(IParseContext context, ITextNode textNode, string attributeName = "Name") { return(!string.IsNullOrEmpty(textNode.Value) ? textNode : base.GetItemNameTextNode(context, textNode, attributeName)); }
public int ConvertToParentIndex(int index, IParseContext context) { return(Parent == null ? index : Parent.ConvertToParentIndex(index, this)); }
object IParseHandler.Create(object parent, IParseContext context, XElement element) => this.Create((TParent)parent, context, element);
public abstract object Create(TParent parent, IParseContext context, XElement element);
public override State PushChar(char c, IParseContext context, ref string rollback) { XElement element = context.Nodes.Peek() as XElement; if (element == null || element.IsComplete) { element = new XElement(context.LocationMinus(2)); // 2 == < + current char context.Nodes.Push(element); } if (c == '<') { if (element.IsNamed) { context.LogError("Unexpected '<' in tag '" + element.Name.FullName + "'."); Close(element, context, context.LocationMinus(1)); } else { context.LogError("Unexpected '<' in unnamed tag."); } rollback = string.Empty; return(Parent); } Debug.Assert(!element.IsComplete); if (element.IsClosed && c != '>') { if (char.IsWhiteSpace(c)) { context.LogWarning("Unexpected whitespace after '/' in self-closing tag."); return(null); } context.LogError("Unexpected character '" + c + "' after '/' in self-closing tag."); context.Nodes.Pop(); return(Parent); } //if tag closed if (c == '>') { if (context.StateTag == MAYBE_SELF_CLOSING) { element.Close(element); } if (!element.IsNamed) { context.LogError("Tag closed prematurely."); } else { Close(element, context, context.Location); } return(Parent); } if (c == '/') { context.StateTag = MAYBE_SELF_CLOSING; return(null); } if (context.StateTag == ATTEMPT_RECOVERY) { if (XmlChar.IsWhitespace(c)) { context.StateTag = RECOVERY_FOUND_WHITESPACE; } return(null); } if (context.StateTag == RECOVERY_FOUND_WHITESPACE) { if (!XmlChar.IsFirstNameChar(c)) { return(null); } } context.StateTag = OK; if (!element.IsNamed && XmlChar.IsFirstNameChar(c)) { rollback = string.Empty; return(NameState); } if (context.CurrentStateLength > 1 && XmlChar.IsFirstNameChar(c)) { rollback = string.Empty; return(AttributeState); } if (XmlChar.IsWhitespace(c)) { return(null); } context.LogError("Unexpected character '" + c + "' in tag.", context.LocationMinus(1)); context.StateTag = ATTEMPT_RECOVERY; return(null); }
public async Task ParseAsync(IParseContext context) { await _advertisementRepository.AddAdvertisementsAsync(context); }
//public static object ApiAdd(IRequest context) //{ // var siteId = context.GetPostInt("siteId"); // var productId = context.GetPostString("productId"); // var productName = context.GetPostString("productName"); // var imageUrl = context.GetPostString("imageUrl"); // var linkUrl = context.GetPostString("linkUrl"); // var fee = context.GetPostDecimal("fee"); // var isDelivery = context.GetPostBool("isDelivery"); // var count = context.GetPostInt("count", 1); // var sessionId = context.GetPostString("sessionId"); // var cartInfo = new CartInfo // { // SiteId = siteId, // UserName = context.UserName, // SessionId = sessionId, // ProductId = productId, // ProductName = productName, // ImageUrl = imageUrl, // LinkUrl = linkUrl, // Fee = fee, // IsDelivery = isDelivery, // Count = count, // AddDate = DateTime.Now // }; // var cartId = CartRepository.GetCartId(siteId, sessionId, productId); // if (cartId == 0) // { // cartId = CartRepository.Insert(cartInfo); // } // else // { // cartInfo = CartRepository.GetCartInfo(cartId); // cartInfo.UserName = context.UserName; // cartInfo.ProductName = productName; // cartInfo.ImageUrl = imageUrl; // cartInfo.LinkUrl = linkUrl; // cartInfo.Fee = fee; // cartInfo.IsDelivery = isDelivery; // cartInfo.Count += count; // cartInfo.AddDate = DateTime.Now; // CartRepository.Update(cartInfo); // } // return cartId; //} public static string Parse(IParseContext context) { var productId = string.Empty; var productName = string.Empty; var imageUrl = string.Empty; var linkUrl = string.Empty; decimal fee = 0; var isDelivery = true; int count = 1; var successUrl = string.Empty; foreach (var attriName in context.StlAttributes.AllKeys) { var value = context.StlAttributes[attriName]; if (Utils.EqualsIgnoreCase(attriName, nameof(CartInfo.ProductId))) { productId = Context.ParseApi.ParseAttributeValue(value, context); } else if (Utils.EqualsIgnoreCase(attriName, nameof(CartInfo.ProductName))) { productName = Context.ParseApi.ParseAttributeValue(value, context); } else if (Utils.EqualsIgnoreCase(attriName, nameof(CartInfo.ImageUrl))) { imageUrl = Context.ParseApi.ParseAttributeValue(value, context); } else if (Utils.EqualsIgnoreCase(attriName, nameof(CartInfo.LinkUrl))) { linkUrl = Context.ParseApi.ParseAttributeValue(value, context); } else if (Utils.EqualsIgnoreCase(attriName, nameof(CartInfo.Fee))) { value = Context.ParseApi.ParseAttributeValue(value, context); decimal.TryParse(value, out fee); } else if (Utils.EqualsIgnoreCase(attriName, nameof(CartInfo.IsDelivery))) { value = Context.ParseApi.ParseAttributeValue(value, context); bool.TryParse(value, out isDelivery); } else if (Utils.EqualsIgnoreCase(attriName, nameof(CartInfo.Count))) { value = Context.ParseApi.ParseAttributeValue(value, context); int.TryParse(value, out count); } else if (Utils.EqualsIgnoreCase(attriName, AttributeSuccessUrl)) { successUrl = Context.ParseApi.ParseAttributeValue(value, context); } } var stlAnchor = new HtmlAnchor(); foreach (var attributeName in context.StlAttributes.AllKeys) { stlAnchor.Attributes.Add(attributeName, context.StlAttributes[attributeName]); } stlAnchor.InnerHtml = Context.ParseApi.Parse(context.StlInnerHtml, context); stlAnchor.HRef = "javascript:;"; var pluginUrl = Context.PluginApi.GetPluginUrl(Main.PluginId); var jqueryUrl = $"{pluginUrl}/assets/js/jquery.min.js"; var utilsUrl = $"{pluginUrl}/assets/js/utils.js"; var apiAddUrl = $"{Context.Environment.ApiUrl}/{Main.PluginId}/apiAdd"; var script = $@" <script type=""text/javascript"" src=""{jqueryUrl}""></script> <script type=""text/javascript"" src=""{utilsUrl}""></script> <script type=""text/javascript""> function addToCart_{productId}(){{ var sessionId = shoppingGetSessionId(); $.ajax({{ url : ""{apiAddUrl}"", xhrFields: {{ withCredentials: true }}, type: ""POST"", data: JSON.stringify({{ siteId: '{context.SiteId}', productId: '{productId}', productName: '{productName}', imageUrl: '{imageUrl}', linkUrl: '{linkUrl}', fee: {fee}, isDelivery: {isDelivery.ToString().ToLower()}, count: {count}, sessionId: sessionId }}), contentType: ""application/json; charset=utf-8"", dataType: ""json"", success: function(data) {{ location.href = '{successUrl}'; }}, error: function (err) {{ var err = JSON.parse(err.responseText); console.log(err.message); }} }}); }} </script> "; stlAnchor.Attributes["onclick"] = $"addToCart_{productId}();return false;"; return($"{script}{GetControlRenderHtml(stlAnchor)}"); }
public static string Parse(IParseContext context) { var type = string.Empty; var redirectUrl = string.Empty; ParseUtils.RegisterBodyHtml(context); var stlAnchor = new HtmlAnchor(); foreach (var name in context.StlAttributes.AllKeys) { var value = context.StlAttributes[name]; if (Utils.EqualsIgnoreCase(name, AttributeType)) { type = Context.ParseApi.ParseAttributeValue(value, context); } else if (Utils.EqualsIgnoreCase(name, AttributeRedirectUrl)) { redirectUrl = Context.ParseApi.ParseAttributeValue(value, context); } else { stlAnchor.Attributes.Add(name, value); } } if (string.IsNullOrEmpty(redirectUrl)) { redirectUrl = Context.ParseApi.GetCurrentUrl(context); } string text; var url = string.Empty; var onClick = string.Empty; if (Utils.EqualsIgnoreCase(type, OAuthType.Weibo.Value)) { text = "微博登录"; url = $"{ApiUtils.GetAuthUrl(OAuthType.Weibo)}?redirectUrl={HttpUtility.UrlEncode(redirectUrl)}"; } else if (Utils.EqualsIgnoreCase(type, OAuthType.Weixin.Value)) { text = "微信登录"; url = $"{ApiUtils.GetAuthUrl(OAuthType.Weixin)}?redirectUrl={HttpUtility.UrlEncode(redirectUrl)}"; } else if (Utils.EqualsIgnoreCase(type, OAuthType.Qq.Value)) { text = "QQ登录"; url = $"{ApiUtils.GetAuthUrl(OAuthType.Qq)}?redirectUrl={HttpUtility.UrlEncode(redirectUrl)}"; } else if (Utils.EqualsIgnoreCase(type, TypeAll)) { text = "一键登录"; onClick = ParseUtils.OnClickLoginAll; } else { text = "登录"; onClick = ParseUtils.OnClickLogin; } stlAnchor.HRef = string.IsNullOrEmpty(url) ? "javascript:;" : url; if (!string.IsNullOrEmpty(onClick)) { stlAnchor.Attributes.Add("onclick", onClick); } stlAnchor.InnerHtml = Context.ParseApi.Parse(context.StlInnerHtml, context); if (string.IsNullOrWhiteSpace(stlAnchor.InnerHtml)) { stlAnchor.InnerHtml = text; } return(Utils.GetControlRenderHtml(stlAnchor)); }
//public static object ApiPay(IRequest request) //{ // var siteId = request.GetPostInt("siteId"); // var channelId = request.GetPostInt("channelId"); // var contentId = request.GetPostInt("contentId"); // var amount = request.GetPostDecimal("amount"); // var channel = request.GetPostString("channel"); // var message = request.GetPostString("message"); // var isMobile = request.GetPostBool("isMobile"); // var successUrl = request.GetPostString("successUrl"); // var orderNo = Regex.Replace(Convert.ToBase64String(Guid.NewGuid().ToByteArray()), "[/+=]", ""); // successUrl += "&orderNo=" + orderNo; // var paymentApi = new PaymentApi(siteId); // var recordInfo = new RecordInfo // { // SiteId = siteId, // ChannelId = channelId, // ContentId = contentId, // Message = message, // Amount = amount, // OrderNo = orderNo, // IsPaied = false, // AddDate = DateTime.Now // }; // RecordDao.Insert(recordInfo); // if (channel == "alipay") // { // return isMobile // ? paymentApi.ChargeByAlipayMobi("文章打赏", amount, orderNo, successUrl) // : paymentApi.ChargeByAlipayPc("文章打赏", amount, orderNo, successUrl); // } // if (channel == "weixin") // { // var notifyUrl = $"{Context.PluginApi.GetPluginApiUrl(Main.PluginId)}/{nameof(ApiWeixinNotify)}/{orderNo}"; // var url = HttpUtility.UrlEncode(paymentApi.ChargeByWeixin("文章打赏", amount, orderNo, notifyUrl)); // var qrCodeUrl = // $"{Context.PluginApi.GetPluginApiUrl(Main.PluginId)}/{nameof(ApiQrCode)}?qrcode={url}"; // return new // { // qrCodeUrl, // orderNo // }; // } // if (channel == "jdpay") // { // return paymentApi.ChargeByJdpay("文章打赏", amount, orderNo, successUrl); // } // return null; //} //public static HttpResponseMessage ApiQrCode(IRequest request) //{ // var response = new HttpResponseMessage(); // var qrcode = request.GetQueryString("qrcode"); // var qrCodeEncoder = new QRCodeEncoder // { // QRCodeEncodeMode = QRCodeEncoder.ENCODE_MODE.BYTE, // QRCodeErrorCorrect = QRCodeEncoder.ERROR_CORRECTION.M, // QRCodeVersion = 0, // QRCodeScale = 4 // }; // //将字符串生成二维码图片 // var image = qrCodeEncoder.Encode(qrcode, Encoding.Default); // //保存为PNG到内存流 // var ms = new MemoryStream(); // image.Save(ms, ImageFormat.Png); // response.Content = new ByteArrayContent(ms.GetBuffer()); // response.Content.Headers.ContentType = new MediaTypeHeaderValue("image/png"); // response.StatusCode = HttpStatusCode.OK; // return response; //} //public static HttpResponseMessage ApiWeixinNotify(IRequest request, string orderNo) //{ // var siteId = request.GetPostInt("siteId"); // var paymentApi = new PaymentApi(siteId); // var response = new HttpResponseMessage(); // bool isPaied; // string responseXml; // paymentApi.NotifyByWeixin(HttpContext.Current.Request, out isPaied, out responseXml); // if (isPaied) // { // RecordDao.UpdateIsPaied(orderNo); // } // response.Content = new StringContent(responseXml); // response.Content.Headers.ContentType = new MediaTypeHeaderValue("application/xml"); // response.StatusCode = HttpStatusCode.OK; // return response; //} //public static object ApiPaySuccess(IRequest request) //{ // var orderNo = request.GetPostString("orderNo"); // RecordDao.UpdateIsPaied(orderNo); // return null; //} //public static object ApiWeixinInterval(IRequest request) //{ // var orderNo = request.GetPostString("orderNo"); // var isPaied = RecordDao.IsPaied(orderNo); // return new // { // isPaied // }; //} public static string Parse(IParseContext context) { var config = Context.ConfigApi.GetConfig <ConfigInfo>(Main.PluginId, context.SiteId); if (!config.IsEnabled || context.ChannelId == 0 || context.ContentId == 0) { return(string.Empty); } var weixinName = string.Empty; foreach (var attriName in context.StlAttributes.AllKeys) { var value = context.StlAttributes[attriName]; if (Utils.EqualsIgnoreCase(attriName, AttributeWeixinName)) { weixinName = Context.ParseApi.ParseAttributeValue(value, context); } } string template; if (!string.IsNullOrEmpty(context.StlInnerHtml)) { template = Context.ParseApi.Parse(context.StlInnerHtml, context); } else { if (!string.IsNullOrEmpty(weixinName)) { weixinName = $@"<p style=""text-align: center"">{weixinName}</p>"; } template = $@" <div class=""detail_zan""> {config.Description} <div @click=""open"" class=""detail_btn""> 赞赏支持 </div> </div> <div class=""mask1_bg mask1_bg_cut"" v-show=""isReward || isWxQrCode || isRewardSuccess"" @click=""isReward = isWxQrCode = isRewardSuccess = false""></div> <div class=""detail_alert detail_alert_cut"" v-show=""isReward""> <div class=""close"" @click=""isReward = isWxQrCode = isRewardSuccess = false""></div> <div class=""alert_input""> 赞赏金额(元):<input type=""text"" v-model.number=""amount"" /> </div> <div class=""alert_textarea""> <textarea v-model=""message"" placeholder=""留言""></textarea> </div> <div class=""pay_list""> <p>支付方式</p> <ul> <li v-show=""(isAlipayPc && !isMobile) || (isAlipayMobi && isMobile)"" :class=""{{ pay_cut: channel === 'alipay' }}"" @click=""channel = 'alipay'"" class=""channel_alipay""><b></b></li> <li v-show=""isWeixin"" :class=""{{ pay_cut: channel === 'weixin' }}"" @click=""channel = 'weixin'"" class=""channel_weixin""><b></b></li> <li v-show=""isJdpay"" :class=""{{ pay_cut: channel === 'jdpay' }}"" @click=""channel = 'jdpay'"" class=""channel_jdpay""><b></b></li> </ul> <div class=""mess_text""></div> <a href=""javascript:;"" @click=""pay"" class=""pay_go"">立即支付</a> </div> </div> <div class=""detail_alert detail_alert_cut"" v-show=""isWxQrCode""> <div class=""close"" @click=""isReward = isWxQrCode = isRewardSuccess = false""></div> <div class=""pay_list""> <p style=""text-align: center"">打开手机微信,扫一扫下面的二维码,即可完成支付</p> {weixinName} <p style=""margin-left: 195px;margin-bottom: 80px;""><img :src=""qrCodeUrl"" style=""width: 200px;height: 200px;""></p> </div> </div> <div class=""detail_alert detail_alert_cut"" v-show=""isRewardSuccess""> <div class=""close"" @click=""isReward = isWxQrCode = isRewardSuccess = false""></div> <div class=""pay_list""> <p style=""text-align: center"">支付成功,谢谢支持</p> <div class=""mess_text""></div> <a href=""javascript:;"" @click=""isReward = isWxQrCode = isRewardSuccess = false"" class=""pay_go"">关闭</a> </div> </div> "; } var apiUrl = Context.Environment.ApiUrl; var elementId = "el-" + Guid.NewGuid(); var vueId = "v" + Guid.NewGuid().ToString().Replace("-", string.Empty); var styleUrl = Context.PluginApi.GetPluginUrl(Main.PluginId, "assets/css/style.css"); var jqueryUrl = Context.PluginApi.GetPluginUrl(Main.PluginId, "assets/js/jquery.min.js"); var vueUrl = Context.PluginApi.GetPluginUrl(Main.PluginId, "assets/js/vue.min.js"); var deviceUrl = Context.PluginApi.GetPluginUrl(Main.PluginId, "assets/js/device.min.js"); var apiPayUrl = UrlUtils.GetPayUrl(apiUrl); var apiPaySuccessUrl = UrlUtils.GetPaySuccessUrl(apiUrl); var successUrl = UrlUtils.GetSuccessUrl(context); var apiWxPayIntervalUrl = UrlUtils.GetWxPayIntervalUrl(apiUrl); var apiStatusUrl = UrlUtils.GetStatusUrl(apiUrl); var paymentApi = new SS.Payment.Core.PaymentApi(context.SiteId); return($@" <link rel=""stylesheet"" type=""text/css"" href=""{styleUrl}"" /> <script type=""text/javascript"" src=""{jqueryUrl}""></script> <script type=""text/javascript"" src=""{vueUrl}""></script> <script type=""text/javascript"" src=""{deviceUrl}""></script> <div id=""{elementId}""> {template} </div> <script type=""text/javascript""> var match = location.search.match(new RegExp(""[\?\&]isRewardSuccess=([^\&]+)"", ""i"")); var isRewardSuccess = (!match || match.length < 1) ? false : true; var {vueId} = new Vue({{ el: '#{elementId}', data: {{ amount: {config.DefaultAmount:N2}, message: '', isAliPay: {paymentApi.IsAliPay.ToString().ToLower()}, isWxPay: {paymentApi.IsWxPay.ToString().ToLower()}, isMobile: device.mobile(), channel: 'alipay', isReward: false, isWxQrCode: false, isRewardSuccess: isRewardSuccess, qrCodeUrl: '' }}, methods: {{ open: function () {{ this.isReward = true; }}, weixinInterval: function(orderNo) {{ var $this = this; var interval = setInterval(function(){{ $.ajax({{ url : ""{apiWxPayIntervalUrl}"", type: ""POST"", data: JSON.stringify({{orderNo: orderNo}}), contentType: ""application/json; charset=utf-8"", dataType: ""json"", success: function(data) {{ if (data.isPaied) {{ clearInterval(interval); $this.isReward = $this.isWxQrCode = false; $this.isRewardSuccess = true; }} }}, error: function (err) {{ var err = JSON.parse(err.responseText); console.log(err.message); }} }}); }}, 3000); }}, pay: function () {{ if (this.amount == 0) return; var $this = this; var data = {{ siteId: '{context.SiteId}', channelId: {context.ChannelId}, contentId: {context.ContentId}, amount: this.amount, channel: this.channel, message: this.message, isMobile: this.isMobile, successUrl: ""{successUrl}"" }}; $.ajax({{ url : ""{apiPayUrl}"", type: ""POST"", data: JSON.stringify(data), contentType: ""application/json; charset=utf-8"", dataType: ""json"", success: function(charge) {{ if ($this.channel === 'weixin') {{ $this.isReward = false; $this.isWxQrCode = true; $this.qrCodeUrl = charge.qrCodeUrl; $this.weixinInterval(charge.orderNo); }} else {{ document.write(charge); }} }}, error: function (err) {{ var err = JSON.parse(err.responseText); console.log(err.message); }} }}); }} }} }}); match = location.search.match(new RegExp(""[\?\&]orderNo=([^\&]+)"", ""i"")); var orderNo = (!match || match.length < 1) ? '' : decodeURIComponent(match[1]); if (isRewardSuccess) {{ $(document).ready(function(){{ $.ajax({{ url : ""{apiPaySuccessUrl}"", type: ""POST"", data: JSON.stringify({{ orderNo: orderNo }}), contentType: ""application/json; charset=utf-8"", dataType: ""json"", success: function(data) {{ console.log(data); }}, error: function (err) {{ var err = JSON.parse(err.responseText); console.log(err.message); }} }}); }}); }} </script> "); }
public static string Parse(IParseContext context) { var stlAnchor = new HtmlAnchor(); var productId = string.Empty; var productName = string.Empty; decimal fee = 0; var loginUrl = string.Empty; var redirectUrl = string.Empty; var weixinName = string.Empty; var isForceLogin = false; foreach (var name in context.StlAttributes.AllKeys) { var value = context.StlAttributes[name]; if (Utils.EqualsIgnoreCase(name, AttributeProductId)) { productId = Context.ParseApi.ParseAttributeValue(value, context); } else if (Utils.EqualsIgnoreCase(name, AttributeProductName)) { productName = Context.ParseApi.ParseAttributeValue(value, context); } else if (Utils.EqualsIgnoreCase(name, AttributeFee)) { value = Context.ParseApi.ParseAttributeValue(value, context); decimal.TryParse(value, out fee); } else if (Utils.EqualsIgnoreCase(name, AttributeLoginUrl)) { loginUrl = Context.ParseApi.ParseAttributeValue(value, context); } else if (Utils.EqualsIgnoreCase(name, AttributeRedirectUrl)) { redirectUrl = Context.ParseApi.ParseAttributeValue(value, context); } else if (Utils.EqualsIgnoreCase(name, AttributeWeixinName)) { weixinName = Context.ParseApi.ParseAttributeValue(value, context); } else if (Utils.EqualsIgnoreCase(name, AttributeIsForceLogin)) { isForceLogin = Utils.ToBool(Context.ParseApi.ParseAttributeValue(value, context)); } else { stlAnchor.Attributes.Add(name, value); } } if (string.IsNullOrEmpty(loginUrl)) { loginUrl = "/home/#/login"; } var currentUrl = Context.ParseApi.GetCurrentUrl(context); var loginToPaymentUrl = $"{loginUrl}?redirectUrl={HttpUtility.UrlEncode(currentUrl)}"; if (string.IsNullOrEmpty(productName) || fee <= 0) { return(string.Empty); } if (!string.IsNullOrEmpty(weixinName)) { weixinName = $@"<p style=""text-align: center"">{weixinName}</p>"; } string template = $@" <div class=""mask1_bg mask1_bg_cut"" v-show=""isPayment || isWxQrCode || isPaymentSuccess"" @click=""isPayment = isWxQrCode = isPaymentSuccess = false"" style=""display: none""></div> <div class=""detail_alert detail_alert_cut"" v-show=""isPayment"" style=""display: none""> <div class=""close"" @click=""isPayment = isWxQrCode = isPaymentSuccess = false""></div> <div class=""alert_input""> 金额: ¥{fee:N2}元 </div> <div class=""alert_textarea""> <textarea v-model=""message"" placeholder=""留言""></textarea> </div> <div class=""pay_list""> <p>支付方式</p> <ul> <li v-show=""(isAlipayPc && !isMobile) || (isAlipayMobi && isMobile)"" :class=""{{ pay_cut: channel === 'alipay' }}"" @click=""channel = 'alipay'"" class=""channel_alipay""><b></b></li> <li v-show=""isWeixin"" :class=""{{ pay_cut: channel === 'weixin' }}"" @click=""channel = 'weixin'"" class=""channel_weixin""><b></b></li> <li v-show=""isJdpay"" :class=""{{ pay_cut: channel === 'jdpay' }}"" @click=""channel = 'jdpay'"" class=""channel_jdpay""><b></b></li> </ul> <div class=""mess_text""></div> <a href=""javascript:;"" @click=""pay"" class=""pay_go"">立即支付</a> </div> </div> <div class=""detail_alert detail_alert_cut"" v-show=""isWxQrCode"" style=""display: none""> <div class=""close"" @click=""isPayment = isWxQrCode = isPaymentSuccess = false""></div> <div class=""pay_list""> <p style=""text-align: center""> 打开手机微信,扫一扫下面的二维码,即可完成支付</p> {weixinName} <p style=""margin-left: 195px;margin-bottom: 80px;""><img :src=""qrCodeUrl"" style=""width: 200px;height: 200px;""></p> </div> </div> <div class=""detail_alert detail_alert_cut"" v-show=""isPaymentSuccess"" style=""display: none""> <div class=""close"" @click=""isPayment = isWxQrCode = isPaymentSuccess = false""></div> <div class=""pay_list""> <p style=""text-align: center"">支付成功,谢谢支持</p> <div class=""mess_text""></div> <a href=""javascript:;"" @click=""weixinPaiedClose"" class=""pay_go"">关闭</a> </div> </div> "; var pluginUrl = Context.PluginApi.GetPluginUrl(Main.PluginId); var apiUrl = Context.PluginApi.GetPluginApiUrl(Main.PluginId); var elementId = "el-" + Guid.NewGuid(); var vueId = "v" + Guid.NewGuid().ToString().Replace("-", string.Empty); var styleUrl = $"{pluginUrl}/assets/css/style.css"; var jqueryUrl = $"{pluginUrl}/assets/js/jquery.min.js"; var vueUrl = $"{pluginUrl}/assets/js/vue.min.js"; var deviceUrl = $"{pluginUrl}/assets/js/device.min.js"; var apiPayUrl = $"{apiUrl}/{nameof(ApiPay)}"; var apiPaySuccessUrl = $"{apiUrl}/{nameof(ApiPaySuccess)}"; var successUrl = Context.ParseApi.GetCurrentUrl(context) + "?isPaymentSuccess=" + true; var apiWeixinIntervalUrl = $"{apiUrl}/{nameof(ApiWeixinInterval)}"; var apiGetUrl = $"{apiUrl}/{nameof(ApiGet)}"; var paymentApi = new PaymentApi(context.SiteId); var html = $@" <link rel=""stylesheet"" type=""text/css"" href=""{styleUrl}"" /> <script type=""text/javascript"" src=""{jqueryUrl}""></script> <script type=""text/javascript"" src=""{vueUrl}""></script> <script type=""text/javascript"" src=""{deviceUrl}""></script> <span id=""{elementId}""> {template} </span> <script type=""text/javascript""> var match = location.search.match(new RegExp(""[\?\&]isPaymentSuccess=([^\&]+)"", ""i"")); var isPaymentSuccess = (!match || match.length < 1) ? false : true; var {vueId} = new Vue({{ el: '#{elementId}', data: {{ isUserLoggin: false, isForceLogin: {isForceLogin.ToString().ToLower()}, loginUrl: '{loginToPaymentUrl}', message: '', isAlipayPc: {paymentApi.IsAlipayPc.ToString().ToLower()}, isAlipayMobi: {paymentApi.IsAlipayMobi.ToString().ToLower()}, isWeixin: {paymentApi.IsWeixin.ToString().ToLower()}, isJdpay: {paymentApi.IsJdpay.ToString().ToLower()}, isMobile: device.mobile(), channel: 'alipay', isPayment: false, isWxQrCode: false, isPaymentSuccess: isPaymentSuccess, qrCodeUrl: '' }}, methods: {{ open: function () {{ if (this.isForceLogin && !this.isUserLoggin) {{ location.href = this.loginUrl; }} else {{ this.isPayment = true; }} }}, weixinInterval: function(orderNo) {{ var $this = this; var interval = setInterval(function(){{ $.ajax({{ url : ""{apiWeixinIntervalUrl}"", xhrFields: {{ withCredentials: true }}, type: ""POST"", data: JSON.stringify({{orderNo: orderNo}}), contentType: ""application/json; charset=utf-8"", dataType: ""json"", success: function(data) {{ if (data.isPaied) {{ clearInterval(interval); $this.isPayment = $this.isWxQrCode = false; $this.isPaymentSuccess = true; }} }}, error: function (err) {{ var err = JSON.parse(err.responseText); console.log(err.message); }} }}); }}, 3000); }}, weixinPaiedClose: function() {{ this.isPayment = this.isWxQrCode = this.isPaymentSuccess = false; var redirectUrl = '{redirectUrl}'; if (redirectUrl) {{ location.href = '{redirectUrl}'; }} }}, pay: function () {{ var $this = this; var data = {{ siteId: {context.SiteId}, productId: '{productId}', productName: '{productName}', fee: {fee:N2}, channel: this.channel, message: this.message, isMobile: this.isMobile, successUrl: '{successUrl}' }}; $.ajax({{ url : ""{apiPayUrl}"", xhrFields: {{ withCredentials: true }}, type: ""POST"", data: JSON.stringify(data), contentType: ""application/json; charset=utf-8"", dataType: ""json"", success: function(charge) {{ if ($this.channel === 'weixin') {{ $this.isPayment = false; $this.isWxQrCode = true; $this.qrCodeUrl = charge.qrCodeUrl; $this.weixinInterval(charge.orderNo); }} else {{ document.write(charge); }} }}, error: function (err) {{ var err = JSON.parse(err.responseText); console.log(err.message); }} }}); }} }} }}); match = location.search.match(new RegExp(""[\?\&]orderNo=([^\&]+)"", ""i"")); var orderNo = (!match || match.length < 1) ? '' : decodeURIComponent(match[1]); if (isPaymentSuccess) {{ $(document).ready(function(){{ $.ajax({{ url : ""{apiPaySuccessUrl}"", xhrFields: {{ withCredentials: true }}, type: ""POST"", data: JSON.stringify({{ orderNo: orderNo }}), contentType: ""application/json; charset=utf-8"", dataType: ""json"", success: function(data) {{ var redirectUrl = '{redirectUrl}'; if (redirectUrl) location.href = '{redirectUrl}'; }}, error: function (err) {{ var err = JSON.parse(err.responseText); console.log(err.message); }} }}); }}); }} else {{ $.ajax({{ url : ""{apiGetUrl}"", xhrFields: {{ withCredentials: true }}, type: ""POST"", data: JSON.stringify({{ siteId: '{context.SiteId}' }}), contentType: ""application/json; charset=utf-8"", dataType: ""json"", success: function(data) {{ {vueId}.isUserLoggin = data.isUserLoggin; }}, error: function (err) {{ var err = JSON.parse(err.responseText); console.log(err.message); }} }}); }} </script> "; stlAnchor.InnerHtml = Context.ParseApi.Parse(context.StlInnerHtml, context); stlAnchor.HRef = "javascript:;"; stlAnchor.Attributes["onclick"] = $"{vueId}.open()"; return(Utils.GetControlRenderHtml(stlAnchor) + html); }
public override object Create(IFlowElementsContainer parent, IParseContext context, XElement element) { return(action(parent, context, element)); }
protected override int ParseDataCore(IParseContext context, XObject node) { var zOrder = XmlConvert.ToInt32(((XElement)node).Value); return(zOrder); }
protected virtual ExtensionElements ParseExtensionElements(BaseElement parent, IParseContext context, XElement element) { return(null); }
public override State PushChar(char c, IParseContext context, ref string rollback) { switch (context.StateTag) { case SOLIDUS: if (Char.IsLetter(c)) { rollback = String.Empty; return(htmlClosingTagState); } context.StateTag = NONE; break; case BRACKET: if (Char.IsLetter(c)) { rollback = String.Empty; return(htmlTagState); } else if (c == '/') { context.StateTag = SOLIDUS; } else { context.StateTag = NONE; } break; case TRANSITION: rollback = String.Empty; switch (c) { case '{': return(EnsureSetAndAdopted <RazorCodeBlockState> (ref childBlockState)); case '*': return(razorCommentState); case '(': return(expressionState); default: if (context.CurrentStateLength <= 2 || (!Char.IsLetterOrDigit(previousChar) && (Char.IsLetter(c) || c == '_'))) { return(speculativeState); } else { context.StateTag = NONE; } break; } break; case INSIDE_PARENTHESES: if (c == '(') { context.KeywordBuilder.Append(c); } else if (c == ')') { if (context.KeywordBuilder.Length > 0) { context.KeywordBuilder.Remove(0, 1); } if (context.KeywordBuilder.Length == 0) { context.StateTag = NONE; IsInsideParentheses = false; } } break; case NONE: switch (c) { case '(': context.KeywordBuilder.Append(c); context.StateTag = INSIDE_PARENTHESES; IsInsideParentheses = true; break; case '<': if (context.Nodes.Peek() is XElement || !Char.IsLetterOrDigit(previousChar)) { context.StateTag = BRACKET; IsInsideGenerics = false; } else { IsInsideGenerics = true; } break; case '>': IsInsideGenerics = false; break; case '@': context.StateTag = TRANSITION; break; default: previousChar = c; break; } break; } return(null); }
//public static object ApiPaySuccessGet(IRequest context) //{ // var guid = context.GetPostString("guid"); // OrderRepository.UpdateIsPayed(guid); // return OrderRepository.GetOrderInfo(guid); //} public static string Parse(IParseContext context) { var orderUrl = string.Empty; foreach (var attriName in context.StlAttributes.AllKeys) { var value = context.StlAttributes[attriName]; if (Utils.EqualsIgnoreCase(attriName, AttributeOrderUrl)) { orderUrl = Context.ParseApi.ParseAttributeValue(value, context); } } string template; if (!string.IsNullOrEmpty(context.StlInnerHtml)) { template = Context.ParseApi.Parse(context.StlInnerHtml, context); } else { template = @" <div class=""cashier""> <div class=""cashier_title""> 感谢您提交订单,我们将及时为您处理! </div> <div class=""cashier_next""> <div class=""cashier_number""> 订单:<span>{{ orderInfo.guid }}</span> </div> <div class=""cashier_text""> <span>{{ orderInfo.totalCount }}件商品</span><span>收件人:{{ orderInfo.realName }}</span> </div> <div class=""cashier_text1""> </div> </div> <div class=""cashier_alert""> <span>安全提醒:</span>平台及销售商不会以订单异常、系统升级等理由,通过任何方式发送给您退款链接。请您谨防钓鱼链接或诈骗电话! </div> <div class=""cashier_pay""> 支付金额:<span>¥{{ (orderInfo.totalFee + orderInfo.expressCost).toFixed(2) }}</span> </div> <div class=""view_order_bg""> <a href=""javascript:;"" @click=""viewOrder"" class=""view_order"">查看订单</a> </div> </div> "; } var pluginUrl = Context.PluginApi.GetPluginUrl(Main.PluginId); var apiUrl = Context.Environment.ApiUrl; var elementId = "el-" + Guid.NewGuid(); var vueId = "v" + Guid.NewGuid().ToString().Replace("-", string.Empty); var jqueryUrl = $"{pluginUrl}/assets/js/jquery.min.js"; var vueUrl = $"{pluginUrl}/assets/js/vue.min.js"; var baseCssUrl = $"{pluginUrl}/assets/css/base.css"; var apiGetUrl = $"{apiUrl}/{Main.PluginId}/ApiPaySuccessGet"; return($@" <script type=""text/javascript"" src=""{jqueryUrl}""></script> <script type=""text/javascript"" src=""{vueUrl}""></script> <link rel=""stylesheet"" type=""text/css"" href=""{baseCssUrl}"" /> <div id=""{elementId}""> {template} </div> <script type=""text/javascript""> var match = location.search.match(new RegExp(""[\?\&]guid=([^\&]+)"", ""i"")); var guid = (!match || match.length < 1) ? """" : decodeURIComponent(match[1]); var {vueId} = new Vue({{ el: '#{elementId}', data: {{ orderInfo: {{}} }}, methods: {{ viewOrder: function () {{ location.href = '{orderUrl}?guid=' + guid; }} }} }}); $(document).ready(function(){{ if (!guid) return; $.ajax({{ url : ""{apiGetUrl}"", xhrFields: {{ withCredentials: true }}, type: ""POST"", data: JSON.stringify({{ guid: guid }}), contentType: ""application/json; charset=utf-8"", dataType: ""json"", success: function(data) {{ {vueId}.orderInfo = data; }}, error: function (err) {{ var err = JSON.parse(err.responseText); console.log(err.message); }} }}); }}); </script> "); }
public override State PushChar(char c, IParseContext context, ref string rollback) { XAttribute att = context.Nodes.Peek() as XAttribute; if (c == '<') { //parent handles message if (att != null) { context.Nodes.Pop(); } rollback = string.Empty; return(Parent); } //state has just been entered if (context.CurrentStateLength == 1) { if (context.PreviousState is XmlNameState) { Debug.Assert(att.IsNamed); context.StateTag = GETTINGEQ; } else if (context.PreviousState is XmlAttributeValueState) { //Got value, so end attribute context.Nodes.Pop(); att.End(context.LocationMinus(1)); IAttributedXObject element = (IAttributedXObject)context.Nodes.Peek(); element.Attributes.AddAttribute(att); rollback = string.Empty; return(Parent); } else { //starting a new attribute Debug.Assert(att == null); Debug.Assert(context.StateTag == NAMING); att = new XAttribute(context.LocationMinus(1)); context.Nodes.Push(att); rollback = string.Empty; return(XmlNameState); } } if (c == '>') { context.LogWarning("Attribute ended unexpectedly with '>' character."); if (att != null) { context.Nodes.Pop(); } rollback = string.Empty; return(Parent); } if (context.StateTag == GETTINGEQ) { if (char.IsWhiteSpace(c)) { return(null); } else if (c == '=') { context.StateTag = GETTINGVAL; return(null); } } else if (context.StateTag == GETTINGVAL) { if (char.IsWhiteSpace(c)) { return(null); } else if (c == '"') { return(DoubleQuotedAttributeValueState); } else if (c == '\'') { return(SingleQuotedAttributeValueState); } else if (char.IsLetterOrDigit(c)) { rollback = string.Empty; return(UnquotedAttributeValueState); } } if (char.IsLetterOrDigit(c) || char.IsPunctuation(c) || char.IsWhiteSpace(c)) { if (context.StateTag == GETTINGEQ) { context.LogError("Expecting = in attribute, got " + c + "."); } else if (context.StateTag == GETTINGVAL) { context.LogError("Expecting attribute value, got " + c + "."); } else { context.LogError("Unexpected character '" + c + "' in attribute."); } if (att != null) { context.Nodes.Pop(); } rollback = string.Empty; return(Parent); } rollback = string.Empty; return(Parent); }
public override State PushChar(char c, IParseContext context, ref string rollback) { if (c == '<') { if (context.StateTag != FREE) { context.LogError("Incomplete tag opening; encountered unexpected '<'.", new MonoDevelop.Projects.Dom.DomRegion( context.LocationMinus(LengthFromOpenBracket(context) + 1), context.LocationMinus(1))); } context.StateTag = BRACKET; return(null); } switch (context.StateTag) { case FREE: //FIXME: handle entities? return(null); case BRACKET: if (c == '?') { rollback = string.Empty; return(this.ProcessingInstructionState); } else if (c == '!') { context.StateTag = BRACKET_EXCLAM; return(null); } else if (c == '/') { return(this.ClosingTagState); } else if (char.IsLetter(c) || c == '_') { rollback = string.Empty; return(TagState); } break; case BRACKET_EXCLAM: if (c == '[') { context.StateTag = CDATA; return(null); } else if (c == '-') { context.StateTag = COMMENT; return(null); } else if (c == 'D') { context.StateTag = DOCTYPE; return(null); } break; case COMMENT: if (c == '-') { return(CommentState); } break; case CDATA: string cdataStr = "CDATA["; if (c == cdataStr [context.KeywordBuilder.Length]) { context.KeywordBuilder.Append(c); if (context.KeywordBuilder.Length < cdataStr.Length) { return(null); } else { return(CDataState); } } else { context.KeywordBuilder.Length = 0; } break; case DOCTYPE: string docTypeStr = "OCTYPE"; if (c == docTypeStr [context.KeywordBuilder.Length]) { context.KeywordBuilder.Append(c); if (context.KeywordBuilder.Length < docTypeStr.Length) { return(null); } else { return(DocTypeState); } } else { context.KeywordBuilder.Length = 0; } break; } context.LogError("Incomplete tag opening; encountered unexpected character '" + c + "'.", new MonoDevelop.Projects.Dom.DomRegion( context.LocationMinus(LengthFromOpenBracket(context)), context.Location)); context.StateTag = FREE; return(null); }
public override State PushChar(char c, IParseContext context, ref string rollback) { INamedXObject namedObject = context.Nodes.Peek() as INamedXObject; if (namedObject == null || namedObject.Name.Prefix != null) { throw new InvalidOperationException("Invalid state"); } Debug.Assert(context.CurrentStateLength > 1 || char.IsLetter(c) || c == '_', "First character pushed to a XmlTagNameState must be a letter."); Debug.Assert(context.CurrentStateLength > 1 || context.KeywordBuilder.Length == 0, "Keyword builder must be empty when state begins."); if (c == ':') { if (namedObject.Name.Name != null || context.KeywordBuilder.Length == 0) { context.LogError("Unexpected ':' in name."); return(Parent); } namedObject.Name = new XName(context.KeywordBuilder.ToString()); context.KeywordBuilder.Length = 0; return(null); } if (XmlChar.IsWhitespace(c) || c == '<' || c == '>' || c == '/' || c == '=') { rollback = string.Empty; if (context.KeywordBuilder.Length == 0) { context.LogError("Zero-length name."); } else if (namedObject.Name.Name != null) { //add prefix (and move current "name" to prefix) namedObject.Name = new XName(namedObject.Name.Name, context.KeywordBuilder.ToString()); } else { namedObject.Name = new XName(context.KeywordBuilder.ToString()); } //note: parent's MalformedTagState logs an error, so skip this //if (c == '<') //context.LogError ("Unexpected '<' in name."); return(Parent); } if (c == ':') { if (namedObject.Name.Name != null || context.KeywordBuilder.Length == 0) { context.LogError("Unexpected ':' in name."); return(Parent); } namedObject.Name = new XName(context.KeywordBuilder.ToString()); context.KeywordBuilder.Length = 0; return(null); } if (XmlChar.IsNameChar(c)) { context.KeywordBuilder.Append(c); return(null); } rollback = string.Empty; context.LogError("Unexpected character '" + c + "' in name"); return(Parent); }
public override State PushChar(char c, IParseContext context, ref string rollback) { XClosingTag ct = context.Nodes.Peek() as XClosingTag; if (ct == null) { Debug.Assert(context.CurrentStateLength == 1, "IncompleteNode must not be an XClosingTag when CurrentStateLength is 1"); Debug.Assert(context.Nodes.Peek() is XElement); ct = new XClosingTag(context.LocationMinus(3)); //3 = </ and the current char context.Nodes.Push(ct); } //if tag closed if (c == '>') { context.Nodes.Pop(); if (ct.IsNamed) { ct.End(context.Location); // walk up tree of parents looking for matching tag int popCount = 0; bool found = false; foreach (XObject node in context.Nodes) { popCount++; XElement element = node as XElement; if (element != null && element.Name == ct.Name) { found = true; break; } } if (!found) { popCount = 0; } //clear the stack of intermediate unclosed tags while (popCount > 1) { XElement el = context.Nodes.Pop() as XElement; if (el != null) { context.LogError(string.Format( "Unclosed tag '{0}' at line {1}, column {2}.", el.Name.FullName, el.Region.BeginLine, el.Region.BeginColumn), ct.Region); } popCount--; } //close the start tag, if we found it if (popCount > 0) { if (context.BuildTree) { ((XElement)context.Nodes.Pop()).Close(ct); } else { context.Nodes.Pop(); } } else { context.LogError( "Closing tag '" + ct.Name.FullName + "' does not match any currently open tag."); } } else { context.LogError("Closing tag ended prematurely."); } return(Parent); } if (c == '<') { context.LogError("Unexpected '<' in tag."); rollback = string.Empty; return(Parent); } if (!ct.IsNamed && (char.IsLetter(c) || c == '_')) { rollback = string.Empty; return(NameState); } rollback = string.Empty; //note: MalformedTagState logs an error, so skip this //context.LogError ("Unexpected character '" + c + "' in closing tag."); return(MalformedTagState); }
public override State PushChar(char c, IParseContext context, ref string rollback) { if (context.CurrentStateLength == 0 && context.PreviousState is HtmlScriptBodyState) { return(Parent); } //NOTE: This is (mostly) duplicated in HtmlClosingTagState //handle "paragraph" tags implicitly closed by block-level elements if (context.CurrentStateLength == 1 && context.PreviousState is XmlNameState) { XElement element = (XElement)context.Nodes.Peek(); //Note: the node stack will always be at least 1 deep due to the XDocument XElement parent = context.Nodes.Peek(1) as XElement; while (parent != null && parent.Name.IsValid && !parent.Name.HasPrefix && !element.Name.HasPrefix && element.Name.IsValid && !ElementTypes.IsInline(element.Name.Name) && (ElementTypes.IsInline(parent.Name.Name) || ElementTypes.IsParagraph(parent.Name.Name)) ) { context.Nodes.Pop(); context.Nodes.Pop(); if (warnAutoClose) { context.LogWarning(string.Format("Tag '{0}' implicitly closed by tag '{1}'.", parent.Name.Name, element.Name.Name), parent.Region); } //parent.Region.End = element.Region.Start; //parent.Region.End.Column = Math.Max (parent.Region.End.Column - 1, 1); parent.Close(parent); context.Nodes.Push(element); parent = context.Nodes.Peek(1) as XElement; } } State ret = base.PushChar(c, context, ref rollback); if (ret == Parent && c == '>') { var element = context.Nodes.Peek() as XElement; if (element != null && !element.Name.HasPrefix && element.Name.IsValid) { if (element.Name.Name.Equals("script", StringComparison.OrdinalIgnoreCase)) { return(ScriptState); } else if (ElementTypes.IsEmpty(element.Name.Name)) { element.Close(element); context.Nodes.Pop(); if (warnAutoClose) { context.LogWarning(string.Format("Implicitly closed empty tag '{0}'", element.Name.Name), element.Region); } } } } return(ret); }
public virtual object Create(object parent, IParseContext context, XElement element) { this.callback((TParent)parent, context, element); return(element); }