Skip to content

Commit 59b31ab

Browse files
committed
fixed final adpater pattern implementations
1 parent 732ffa8 commit 59b31ab

File tree

3 files changed

+66
-104
lines changed

3 files changed

+66
-104
lines changed

src/WebFormsToBlazorServerCommands/Migration/AspxToBlazorControlConverter.cs

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,6 @@ private async Task<string> ConvertFormViewControl(string nodeContent)
126126

127127
try
128128
{
129-
130129
var editFormNode = model.All.Where(p => p.LocalName.ToLower().Equals("asp:formview")).FirstOrDefault();
131130
var newNode = parser.ParseFragment($"<EditForm Model={editFormNode.GetAttribute("ItemType")} OnValidSubmit={editFormNode.GetAttribute("SelectMethod")}></EditForm>", editFormNode);
132131

@@ -143,7 +142,6 @@ private async Task<string> ConvertFormViewControl(string nodeContent)
143142
foreach (var formObj in aspFormTags)
144143
{
145144
var migratedControlText = await _adapterHost.MigrateTagControl(formObj.NodeName, formObj.OuterHtml);
146-
147145
var tempNode = parser.ParseFragment(migratedControlText, null);
148146

149147
//ParseFragment always adds on a HTML & BODY tags, at least with this call setup. We need to pull out *just* the element that we have migrated.
@@ -197,15 +195,13 @@ private async Task<string> ConvertContentControl(string nodeContent)
197195
try
198196
{
199197
var model = await _angleSharpContext.OpenAsync(req => req.Content(nodeContent));
200-
201198
var contentControlObj = model.Descendents<Element>().First(c => c.TagName.ToLower().Equals("asp:content"));
202199

203200
//send any child asp:* controls to be converted by the a call back out to the adapterHosting class.
204201
var aspFormTags = contentControlObj.Descendents<IElement>().Where(p => p.NodeName.ToLower().Contains("asp:")).ToList();
205202
foreach (var formObj in aspFormTags)
206203
{
207204
var migratedControlText = await _adapterHost.MigrateTagControl(formObj.NodeName, formObj.OuterHtml);
208-
209205
var tempNode = parser.ParseFragment(migratedControlText, null);
210206

211207
//ParseFragment always adds on a HTML & BODY tags, at least with this call setup. We need to pull out *just* the element that we have migrated.

src/WebFormsToBlazorServerCommands/Migration/WebFormToBlazorServerMigration.AspxFiles.cs

Lines changed: 18 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
using AngleSharp.Dom;
1414
using AngleSharp.Html.Parser;
1515
using AngleSharp;
16+
using System.ComponentModel.Design;
1617

1718
namespace WebFormsToBlazorServerCommands.Migration
1819
{
@@ -249,30 +250,30 @@ await _statusTracking.UpdateCurrentStatusAsync(MigrationStepEnum.AspxPages,
249250
}
250251

251252

252-
253-
private static void ProcessSourceElement(Element elementToProcess, ref Element targetParentElement, ref HtmlParser htmlParser)
253+
/// <summary>
254+
/// This method is used to send an Element through any registered ControlConverter adapters and get back
255+
/// the migrated text from the AdapterHost.
256+
/// </summary>
257+
/// <param name="elementToProcess"></param>
258+
/// <returns>String</returns>
259+
private async Task<string> ProcessSourceElement(Element elementToProcess)
254260
{
255261
Element processedElement = null;
262+
StringBuilder processedHTML = new StringBuilder();
256263
var converterAdapter = new ConverterAdapter();
257264
converterAdapter.RegisterControlConverter(new AspxToBlazorControlConverter(converterAdapter));
258265

266+
var htmlParser = new AngleSharp.Html.Parser.HtmlParser();
267+
259268
try
260269
{
261270
//If this is an ASP:* control then call the migration code, append the *entire* migrated node, and return to the calling method.
262271
if (elementToProcess.LocalName.ToLower().Contains("asp:"))
263272
{
264273
var newNodeText = Task.Run(() => converterAdapter.MigrateTagControl(elementToProcess.LocalName, elementToProcess.OuterHtml)).Result;
265-
var convertedNodeObj = htmlParser.ParseFragment(newNodeText, null);
266-
267-
//Need to remove the HTML/HEAD/BODY tags that get added by the parser
268-
var NodeToAppend = convertedNodeObj.GetElementsByTagName("BODY").First().FirstElementChild;
269-
270-
//Append the element to the targetDocumentFragment, or the lastAppendedElement depending
271-
processedElement = targetParentElement.AppendElement(NodeToAppend) as Element;
272274

273275
//We do *not* deal with any children of this element, as that is the responsibility of the MigratTagControl to deal with any children of the ASP control
274-
return;
275-
276+
return newNodeText;
276277
}
277278
else
278279
{
@@ -281,31 +282,25 @@ private static void ProcessSourceElement(Element elementToProcess, ref Element t
281282
// - recursively call this method to deal with the children, passing in the new appended as the parent element to append children too
282283
if (elementToProcess.ChildElementCount > 0)
283284
{
284-
//Make sure that we are not doubling up the HTML and/or the BODY element - these get added by default from AngleSharp even to fragments.
285-
if (!elementToProcess.NodeName.ToLower().Equals(targetParentElement.NodeName.ToLower()))
286-
{
287-
processedElement = targetParentElement.AppendElement(elementToProcess.Clone(false) as Element);
288-
}
285+
processedElement = elementToProcess.Clone(false) as Element;
289286
foreach (Element item in elementToProcess.Children)
290287
{
291-
ProcessSourceElement(item, ref processedElement, ref htmlParser);
288+
var newElement = htmlParser.ParseFragment(await ProcessSourceElement(item), processedElement);
289+
processedElement.Append(newElement.ToArray());
292290
}
293-
291+
processedHTML.Append(processedElement.OuterHtml);
294292
} else
295293
{
296-
targetParentElement.Append(elementToProcess.Clone(false));
294+
processedHTML.Append((elementToProcess.Clone(false) as Element).OuterHtml);
297295
}
298296

299-
return;
300-
297+
return processedHTML.ToString();
301298
}
302299
}
303300
catch (Exception)
304301
{
305-
306302
throw;
307303
}
308-
309304
}
310305

311306
}

src/WebFormsToBlazorServerCommands/Migration/WebFormToBlazorServerMigration.cs

Lines changed: 48 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
using Newtonsoft.Json;
1515
using WebFormsToBlazorServerCommands.Templates;
1616
using CodeFactory.Formatting.CSharp;
17+
using System.Text;
1718

1819
namespace WebFormsToBlazorServerCommands.Migration
1920
{
@@ -177,7 +178,6 @@ private async Task ConvertAspxPage(VsDocument sourcePage, VsProject targetProjec
177178

178179
//Drop the pageHeaderData into the Dictionary for later processing by any downstream T4 factories
179180
conversionData.Add("HeaderData", pageHeaderData);
180-
//just some status text for the dialog ( need to convert this to events )
181181

182182
//Getting the source code from the code behind file provided.
183183
var codeSource = sourceCodeBehind?.SourceCode;
@@ -450,89 +450,60 @@ private async Task<Dictionary<string, string>> ReplaceAspControls(string sourceA
450450
var context = BrowsingContext.New(config);
451451
var scratchSource = sourceAspCode;
452452
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();
455454

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
463456
{
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);
466462

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)
470464
{
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+
}
472492
}
473493

474-
}
475-
494+
if (htmlTag.Success)
495+
{
496+
migratedSource.Insert(0, @"<HTML>");
497+
migratedSource.Append(@"</HTML>");
498+
}
476499

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+
}
536507

537508
return result;
538509
}

0 commit comments

Comments
 (0)