Skip to content

Commit 7066007

Browse files
author
ArthurHub
committed
fix setting html fragment in correct location by selection
1 parent e22db3b commit 7066007

File tree

1 file changed

+46
-18
lines changed

1 file changed

+46
-18
lines changed

Source/HtmlRenderer/Utils/DomUtils.cs

Lines changed: 46 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -437,7 +437,9 @@ public static string GenerateHtml(CssBox root, HtmlGenerationStyle styleGen = Ht
437437
var sb = new StringBuilder();
438438
if (root != null)
439439
{
440-
WriteHtml(sb, root, styleGen, onlySelected ? CollectSelectedBoxes(root) : null);
440+
CssBox selectionRoot = null;
441+
var selectedBoxes = onlySelected ? CollectSelectedBoxes(root, out selectionRoot) : null;
442+
WriteHtml(sb, root, styleGen, selectedBoxes, selectionRoot);
441443
}
442444
return sb.ToString();
443445
}
@@ -532,20 +534,47 @@ private static int GetSelectedPlainText(StringBuilder sb, CssBox box)
532534
}
533535

534536
/// <summary>
535-
/// Collect the html tags that have at least one word down the hierarchy that is selected recursively.<br/>
537+
/// Collect the boxes that have at least one word down the hierarchy that is selected recursively.<br/>
536538
/// </summary>
537539
/// <param name="root">the box to check its sub-tree</param>
540+
/// <param name="selectionRoot">return the box the is the root of selected boxes (the first box to contain multiple selected boxes)</param>
538541
/// <returns>the collection to add the selected tags to</returns>
539-
private static Dictionary<CssBox, bool> CollectSelectedBoxes(CssBox root)
542+
private static Dictionary<CssBox, bool> CollectSelectedBoxes(CssBox root, out CssBox selectionRoot)
540543
{
541-
var selectedTags = new Dictionary<CssBox, bool>();
542-
var maybeTags = new Dictionary<CssBox, bool>();
543-
CollectSelectedBoxes(root, selectedTags, maybeTags);
544-
return selectedTags;
544+
var selectedBoxes = new Dictionary<CssBox, bool>();
545+
var maybeBoxes = new Dictionary<CssBox, bool>();
546+
CollectSelectedBoxes(root, selectedBoxes, maybeBoxes);
547+
548+
// find the box the is the root of selected boxes (the first box to contain multiple selected boxes)
549+
selectionRoot = root;
550+
while (true)
551+
{
552+
bool foundRoot = false;
553+
CssBox selectedChild = null;
554+
foreach (var childBox in selectionRoot.Boxes)
555+
{
556+
if (selectedBoxes.ContainsKey(childBox))
557+
{
558+
if (selectedChild != null)
559+
{
560+
foundRoot = true;
561+
break;
562+
}
563+
selectedChild = childBox;
564+
}
565+
}
566+
567+
if (foundRoot || selectedChild == null)
568+
break;
569+
570+
selectionRoot = selectedChild;
571+
}
572+
573+
return selectedBoxes;
545574
}
546575

547576
/// <summary>
548-
/// Collect the html tags that have at least one word down the hierarchy that is selected recursively.<br/>
577+
/// Collect the boxes that have at least one word down the hierarchy that is selected recursively.<br/>
549578
/// Use <paramref name="maybeBoxes"/> to handle boxes that are between selected words but don't have selected word inside.<br/>
550579
/// </summary>
551580
/// <param name="box">the box to check its sub-tree</param>
@@ -559,10 +588,7 @@ private static bool CollectSelectedBoxes(CssBox box, Dictionary<CssBox, bool> se
559588
{
560589
if (word.Selected)
561590
{
562-
if (box.HtmlTag != null)
563-
{
564-
selectedBoxes.Add(box, true);
565-
}
591+
selectedBoxes[box] = true;
566592
foreach (var maybeTag in maybeBoxes)
567593
selectedBoxes[maybeTag.Key] = maybeTag.Value;
568594
maybeBoxes.Clear();
@@ -575,10 +601,7 @@ private static bool CollectSelectedBoxes(CssBox box, Dictionary<CssBox, bool> se
575601
var childInSelection = CollectSelectedBoxes(childBox, selectedBoxes, maybeBoxes);
576602
if (childInSelection)
577603
{
578-
if (box.HtmlTag != null)
579-
{
580-
selectedBoxes[box] = true;
581-
}
604+
selectedBoxes[box] = true;
582605
isInSelection = true;
583606
}
584607
}
@@ -599,7 +622,8 @@ private static bool CollectSelectedBoxes(CssBox box, Dictionary<CssBox, bool> se
599622
/// <param name="box">the html sub-tree to write</param>
600623
/// <param name="styleGen">Controls the way styles are generated when html is generated</param>
601624
/// <param name="selectedBoxes">Control if to generate only selected boxes, if given only boxes found in hash will be generated</param>
602-
private static void WriteHtml(StringBuilder sb, CssBox box, HtmlGenerationStyle styleGen, Dictionary<CssBox, bool> selectedBoxes)
625+
/// <param name="selectionRoot">the box the is the root of selected boxes (the first box to contain multiple selected boxes)</param>
626+
private static void WriteHtml(StringBuilder sb, CssBox box, HtmlGenerationStyle styleGen, Dictionary<CssBox, bool> selectedBoxes, CssBox selectionRoot)
603627
{
604628
if (box.HtmlTag == null || selectedBoxes == null || selectedBoxes.ContainsKey(box))
605629
{
@@ -609,6 +633,8 @@ private static void WriteHtml(StringBuilder sb, CssBox box, HtmlGenerationStyle
609633
(!box.HtmlTag.Attributes["href"].StartsWith("property") && !box.HtmlTag.Attributes["href"].StartsWith("method")))
610634
{
611635
WriteHtmlTag(sb, box, styleGen);
636+
if( box == selectionRoot )
637+
sb.Append("<!--StartFragment-->");
612638
}
613639

614640
if (styleGen == HtmlGenerationStyle.InHeader && box.HtmlTag.Name == "html" && box.HtmlContainer.CssData != null)
@@ -633,11 +659,13 @@ private static void WriteHtml(StringBuilder sb, CssBox box, HtmlGenerationStyle
633659

634660
foreach (var childBox in box.Boxes)
635661
{
636-
WriteHtml(sb, childBox, styleGen, selectedBoxes);
662+
WriteHtml(sb, childBox, styleGen, selectedBoxes, selectionRoot);
637663
}
638664

639665
if (box.HtmlTag != null && !box.HtmlTag.IsSingle)
640666
{
667+
if (box == selectionRoot)
668+
sb.Append("<!--EndFragment-->");
641669
sb.AppendFormat("</{0}>", box.HtmlTag.Name);
642670
}
643671
}

0 commit comments

Comments
 (0)