|
14 | 14 | using Newtonsoft.Json; |
15 | 15 | using WebFormsToBlazorServerCommands.Templates; |
16 | 16 | using CodeFactory.Formatting.CSharp; |
| 17 | +using System.Text; |
17 | 18 |
|
18 | 19 | namespace WebFormsToBlazorServerCommands.Migration |
19 | 20 | { |
@@ -177,7 +178,6 @@ private async Task ConvertAspxPage(VsDocument sourcePage, VsProject targetProjec |
177 | 178 |
|
178 | 179 | //Drop the pageHeaderData into the Dictionary for later processing by any downstream T4 factories |
179 | 180 | conversionData.Add("HeaderData", pageHeaderData); |
180 | | - //just some status text for the dialog ( need to convert this to events ) |
181 | 181 |
|
182 | 182 | //Getting the source code from the code behind file provided. |
183 | 183 | var codeSource = sourceCodeBehind?.SourceCode; |
@@ -450,89 +450,60 @@ private async Task<Dictionary<string, string>> ReplaceAspControls(string sourceA |
450 | 450 | var context = BrowsingContext.New(config); |
451 | 451 | var scratchSource = sourceAspCode; |
452 | 452 | var model = await context.OpenAsync(req => req.Content(sourceAspCode)); |
453 | | - var parser = context.GetService<HtmlParser>(); |
454 | | - var targetDOM = model.CreateDocumentFragment(); |
| 453 | + StringBuilder migratedSource = new StringBuilder(); |
455 | 454 |
|
456 | | - var testElementsDesc = model.Descendents<IElement>(); |
457 | | - var testNodesDesc = model.Descendents(); |
458 | | - Element targetParentElement = null; |
459 | | - |
460 | | - var domTree = model.Children; |
461 | | - |
462 | | - foreach (Element child in domTree) |
| 455 | + try |
463 | 456 | { |
464 | | - //append a clone of this element to the targetDOM |
465 | | - targetParentElement = targetDOM.AppendElement(child.Clone(false) as Element); |
| 457 | + //Deal with HTML, HEAD and BODY tags (most *.aspx pages won't have these - but we still have to manage those that do) |
| 458 | + //Look through the incoming sourceAspCode parameter and see if we have any of those three tags present. |
| 459 | + var htmlTag = System.Text.RegularExpressions.Regex.Match(sourceAspCode, @"<HTML.*?>(.|\n)*?<\/HTML>", RegexOptions.IgnoreCase); |
| 460 | + var headTag = System.Text.RegularExpressions.Regex.Match(sourceAspCode, @"<HEAD.*?>(.|\n)*?<\/HEAD>", RegexOptions.IgnoreCase); |
| 461 | + var bodyTag = System.Text.RegularExpressions.Regex.Match(sourceAspCode, @"<BODY>(.|\n)*?<\/BODY>", RegexOptions.IgnoreCase); |
466 | 462 |
|
467 | | - //Process any children that this element may have, |
468 | | - //The ProcessSourceElement will append the child node to the target and call itself recursively for any children of the child. |
469 | | - foreach (Element item in child.Children) |
| 463 | + foreach (Element child in model.Children) |
470 | 464 | { |
471 | | - ProcessSourceElement(item, ref targetParentElement, ref parser); |
| 465 | + //The first element will always be an HTML element as that gets added by the AngleSharp parser |
| 466 | + |
| 467 | + //Process the children which will be a HEAD tag and a BODY tag, at a minimum as added by the AngleSharp parser |
| 468 | + //The ProcessSourceElement will append the child node to the target and call itself recursively for any children of the child. |
| 469 | + foreach (Element item in child.Children) |
| 470 | + { |
| 471 | + if (item.NodeName.ToLower().Equals("head")) |
| 472 | + { |
| 473 | + //just take the value of the headTag Regex match from earlier in this method (there are no asp:* controls of any kind that live in the |
| 474 | + //HEAD tag - so we can just copy it down to here) |
| 475 | + migratedSource.Append(headTag.Value); |
| 476 | + } |
| 477 | + if (item.NodeName.ToLower().Equals("body")) |
| 478 | + { |
| 479 | + //We go ahead and process this element. Any children of the tag are actually handled by the ProcessSourceElement() method |
| 480 | + var migratedBodyElement = await ProcessSourceElement(item); |
| 481 | + if (!bodyTag.Success) |
| 482 | + { |
| 483 | + var matches = Regex.Match(migratedBodyElement, @"<body>([\S\s]*)<\/body>", RegexOptions.IgnoreCase); |
| 484 | + migratedSource.Append(matches.Groups[1].Value); |
| 485 | + } else |
| 486 | + { |
| 487 | + migratedSource.Append(migratedBodyElement); |
| 488 | + } |
| 489 | + |
| 490 | + } |
| 491 | + } |
472 | 492 | } |
473 | 493 |
|
474 | | - } |
475 | | - |
| 494 | + if (htmlTag.Success) |
| 495 | + { |
| 496 | + migratedSource.Insert(0, @"<HTML>"); |
| 497 | + migratedSource.Append(@"</HTML>"); |
| 498 | + } |
476 | 499 |
|
477 | | - //var aspContentTags = model.All.Where(p => p.LocalName.ToLower().Equals("asp:content")); |
478 | | - //if (aspContentTags.Any()) |
479 | | - //{ |
480 | | - // result.Add("ContentPlaceHolderID", aspContentTags.First().Attributes.Select(p => p.Name.Equals("ContentPlaceHolderID")).First().ToString()); |
481 | | - // //There should only be a single asp:Content tag per aspx page |
482 | | - //} |
483 | | - |
484 | | - ////Deal with asp:FormView tag |
485 | | - //var aspFormTags = model.All.Where(p => p.LocalName.ToLower().Equals("asp:formview")).ToList(); |
486 | | - //foreach (var formObj in aspFormTags) |
487 | | - //{ |
488 | | - // var newNode = parser.ParseFragment($"<EditForm Model={formObj.GetAttribute("ItemType")} OnValidSubmit={formObj.GetAttribute("SelectMethod")}> </EditForm>", formObj); |
489 | | - // //check for ItemTemplate tag and remove it. There isn't one in Blazor/Razor |
490 | | - // newNode.FirstOrDefault().AppendNodes( |
491 | | - // formObj.Children.Any(p => p.TagName.ToLower().Equals("itemtemplate")) |
492 | | - // ? formObj.Children.First(c => c.TagName.ToLower().Equals("itemtemplate")).Children.ToArray() |
493 | | - // : formObj.ChildNodes.ToArray()); |
494 | | - // formObj.Replace(newNode.ToArray()); |
495 | | - |
496 | | - // result.Add("ItemType", formObj.GetAttribute("ItemType")); |
497 | | - // result.Add("SelectMethod", formObj.GetAttribute("SelectMethod")); |
498 | | - |
499 | | - // scratchSource = model.All.First(p => p.LocalName.ToLower().Equals("body")).InnerHtml; |
500 | | - //} |
501 | | - |
502 | | - ////Look for any tags that have 'asp:' in them -- then drop the 'asp:' from it. |
503 | | - //var aspHelperTags = model.All.Where(p => p.LocalName.ToLower().Contains("asp:")).ToList(); |
504 | | - //bool hasContentTag = false; |
505 | | - //foreach (var tagObj in aspHelperTags) |
506 | | - //{ |
507 | | - // if (tagObj.LocalName.ToLower().Contains("asp:content ")) |
508 | | - // { |
509 | | - // hasContentTag = true; |
510 | | - // continue; |
511 | | - // } |
512 | | - |
513 | | - // //Removing the asp: tag from the html |
514 | | - // var cleanedHtml = Regex.Replace(tagObj.OuterHtml, "asp:", "", RegexOptions.IgnoreCase); |
515 | | - |
516 | | - // //Having the cleanHtml reloaded into the parser. |
517 | | - // var replacementTagNode = parser.ParseFragment(cleanedHtml, tagObj); |
518 | | - |
519 | | - // //Injecting the cleaned up parsed content back into the target tag in the dom. |
520 | | - // tagObj.Replace(replacementTagNode.ToArray()); |
521 | | - |
522 | | - // //var replacementTagNode = |
523 | | - // // parser.ParseFragment(tagObj.OuterHtml.Replace("asp:", ""), tagObj); |
524 | | - // //tagObj.Replace(replacementTagNode.ToArray()); |
525 | | - //} |
526 | | - |
527 | | - //scratchSource = hasContentTag |
528 | | - // ? model.All.First(p => p.LocalName.ToLower().Equals("asp:content")).InnerHtml |
529 | | - // : model.All.First(p => p.LocalName.ToLower().Equals("body")).InnerHtml; |
530 | | - |
531 | | - scratchSource = targetDOM.Descendents<Element>().First(p => p.NodeName.ToLower().Equals("body")).InnerHtml; |
532 | | - //scratchSource = model.All.First(p => p.LocalName.ToLower().Equals("body")).InnerHtml; |
533 | | - |
534 | | - result.Add("source", sourceAspCode); |
535 | | - result.Add("alteredSource", scratchSource); |
| 500 | + result.Add("source", sourceAspCode); |
| 501 | + result.Add("alteredSource", migratedSource.ToString()); |
| 502 | + } |
| 503 | + catch (Exception ex) |
| 504 | + { |
| 505 | + throw; |
| 506 | + } |
536 | 507 |
|
537 | 508 | return result; |
538 | 509 | } |
|
0 commit comments