2016-07-06 6 views
0

У меня есть шаблоны Razor, которые могут быть созданы клиентом на основе WYSIWYG на основе IFrame (в настоящее время SCeditor).Шаблон Razor <table> как действительный чистый HTML для основанного на IFrame WYSIWYG

Примитивные конструкции, такие как <p>@Model.Price</p> или @(Model.CashOnDelivery ? "cash on delivery" : "transfer"), отлично работают в WYSIWYG, однако проблема возникает с <table>. Современные браузеры любят исправлять DOM, а синтаксис Razor между табличными тегами - это не действительно действительный HTML, поэтому то, что у меня есть, конечно, не то, что я вижу.

Например

<table border="1"> 
    <tr> 
     <th>Name</th> 
     <th>Amount</th> 
     <th>Price</th> 
     <th>TotalPrice</th> 
    </tr> 
    @foreach (var service in Model.Services) 
    {<tr> 
     <td>@service.Name</td> 
     <td>@service.Amount</td> 
     <td>@service.ItemPrice</td> 
     <td>@service.TotalPrice</td> 
    </tr>} 
</table> 

при отображении WYSIWYG IFrame DOM становится

@foreach (var service in Model.Services) 
{} 
<table border="1"> 
    <tr> 
     <th>Name</th> 
     <th>Amount</th> 
     <th>Price</th> 
     <th>TotalPrice</th> 
    </tr> 
    <tr> 
     <td>@service.Name</td> 
     <td>@service.Amount</td> 
     <td>@service.ItemPrice</td> 
     <td>@service.TotalPrice</td> 
    </tr> 
</table> 

Так что, когда пользователь нажимает кнопку Сохранить, WYSIWYG дает мне сломанный код, основанный на фиксированной DOM. Chrome, Firefox и IE 10+ выполняют примерно те же исправления.

Я пытался произвести некоторые хаки, как сокрытие Razor поддельных атрибутов, но

  • несбалансированной HTML-теги в источнике причины Razor компиляции сбоя
  • атрибуты в закрывающих тегах не являются действительным HTML либо

Заполнение таблицы с помощью JS не будет работать, поскольку шаблоны часто идут прямо на электронную почту. Переключение с <table> на <div> приведет к отмене функций WYSIWYG из таблиц, поэтому это тоже не очень хороший вариант. Я мог бы скрыть создание таблицы в функции, но опять же, это предотвратит стили WYSIWYGing для нее ...

Подводя итог: мне нужно остановиться с Razor, <table> и динамической генерацией строк, но поддерживать возможности WYSIWYG. Предпочтительно не создавать шаблоны для пользователя в процессе. И у меня все идеи.

ответ

0

Ну, мне удалось создать обходное решение.

я изменил шаблон

<table border="1"> 
    <tr> 
     <th>Name</th> 
     <th>Amount</th> 
     <th>Price</th> 
     <th>TotalPrice</th> 
    </tr> 
    @foreach (var service in Model.Services) 
    {<tr razor-outer="foreach (var service in Model.Services)"> 
     <td>@service.Name</td> 
     <td>@service.Amount</td> 
     <td>@service.ItemPrice</td> 
     <td>@service.TotalPrice</td> 
    </tr>} 
</table> 

, а затем перед отображением в WYSIWYG просто удалить текстовые узлы до и после <tr> узлов с razor-outer атрибутом. Сокрытие кода в процессе атрибута полностью обратимо и WYSIWYG.

public static string PackRazor(string razor) 
{ 
    if (string.IsNullOrWhiteSpace(razor)) 
    { 
     return razor; 
    } 
    HtmlDocument doc = new HtmlDocument(); 

    doc.LoadHtml(razor); 

    string razorOuterXpath = "//*[@razor-outer]"; 

    var nodes = doc.DocumentNode.SelectNodes(razorOuterXpath); 
    if (nodes != null) 
    { 
     foreach (HtmlNode node in nodes) 
     { 
      HtmlAttribute razorAttr = node.Attributes["razor-outer"]; 
      var prev = node.PreviousSibling; 
      var next = node.NextSibling; 

      if (prev.NodeType == HtmlNodeType.Text && prev.InnerHtml.Contains(razorAttr.Value)) 
      { 
       node.ParentNode.RemoveChild(prev); 
      } 
      if (next.NodeType == HtmlNodeType.Text && next.InnerHtml.Contains("}")) 
      { 
       node.ParentNode.RemoveChild(next); 
      } 
     } 
    } 

    return doc.DocumentNode.OuterHtml; 
} 

и перед сохранением шаблона бритву можно восстановить из атрибута

public static string UnpackRazor(string html) 
{ 
    if (string.IsNullOrWhiteSpace(html)) 
    { 
     return html; 
    } 
    HtmlDocument doc = new HtmlDocument(); 

    doc.LoadHtml(html); 

    string razorOuterXpath = "//*[@razor-outer]"; 

    var nodes = doc.DocumentNode.SelectNodes(razorOuterXpath); 
    if (nodes != null) 
    { 
     foreach (HtmlNode node in nodes) 
     { 
      HtmlAttribute razorAttr = node.Attributes["razor-outer"]; 
      var newNode = HtmlNode.CreateNode(html); 
      node.ParentNode.InsertBefore(HtmlNode.CreateNode("@" + razorAttr.Value + "{"), node); 
      node.ParentNode.InsertAfter(HtmlNode.CreateNode("}"), node); 
      Console.WriteLine(razorAttr.Value); 
     } 
    } 

    return doc.DocumentNode.OuterHtml; 
}