# هك صغير: مركب CSS / Minifier ASPM SK2net Control

<datetime class="hidden">2010-03-25T00:00</datetime>

<!-- category -- mostlylucidcouk, Imported -->
**الحذر : عندما أقول هك أعنيه … هذا لا يكون جاهزاً في أي حال . .… إنه . ’ مجرد عينة في هذه المرحلة .**

اعتقدت انني سوف اقوم بعمل جاري على الانترنت لكي يتمكن الناس من اللعب بهذا هذا واحد من مشاريعي الصغيرة[أتذكر دائماً

إذاً , ماذا تفعل

حسناً , واحدة من المشاكل الرئيسية في الأداء للموقع الحالي هو عدد الطلبات التي يقومون بها بالعودة إلى server , ليس сервер الفعلي [كتب عن هذا](http://mostlylucid.net/archive/2008/07/11/spritey.my-pet-project.aspx) بعد قراءة ستيف سوندرز ممتاز ‘[المواقع ذات الأداء العالي’](http://www.amazon.com/High-Performance-Web-Sites-Essential) لقد كانت صراحة مفاجئة بالنسبة لي ! حسنا , على أي حال في الآونة الأخيرة كنت ألعب مع عدد من أجهزة التحكم في الـ ASP ,. ,NET التي تهدف لجعل تحسين عدد المكالماتサーバية يتوجب على تطبيق , . ,net أن يخفض عددها كثيرا . [تحكم CSS Sprite](http://mostlylucid.net/archive/2008/07/11/spritey.my-pet-project.aspx). الأسفل هو بداية الثانية; لقد كتبت هذا في ساعات قليلة الليلة الماضية لأنني لم أستطع ’ النوم لأفكر كيف يمكن أن يعملM SK3 البرمجة صعبة جدًا لكنها تبين مفهومها جيداً

في جوهرها أردت أن أبذل جهداً أقل ممكناً لجمع وضغط العديد &lt;link rel=”stylesheet”&gt; مدخلات ملف CSS معا, تقلصها باستخدام [مضغوط YUI](http://developer.yahoo.com/yui/compressor/) ([من أجل .NET…on Codeplex](http://yuicompressor.codeplex.com/)) وتخرج معتمداً على الوقت (في هذه الحالة, fecha Modified for the fileM SK3 hash for the File name МSK4in a fixed location at the momentMSC5 “~/OutputCSSMNK7 ثم تخرج بطاقة في الصفحة لهذا الملف الجديدMRK8

إذن , كيف يعمل ?

حسنا, تخيل أن لديك صفحة مع بعض تعريفات مصفوف التصميم مثل هذه

```
   1: <link type="text/css" rel="stylesheet" href="../../../build/logger/assets/logger.css"/>
```

```
   2: <link type="text/css" rel="stylesheet" href="../../../build/yuitest/assets/testlogger.css"/>        
```

```
   3: <style type="text/css">
```

```
   4: #container, #container2 {
```

```
   5:     width: 400px;
```

```
   6: }
```

```
   7:  
```

```
   8: .yui-carousel-element {
```

```
   9:     margin: 0;
```

```
  10:     padding: 0;
```

```
  11: }
```

```
  12:  
```

```
  13: .yui-carousel-element li {
```

```
  14:     border: none;
```

```
  15:     margin: 0;
```

```
  16:     padding: 0;
```

```
  17:     width: 100px;
```

```
  18: }
```

```
  19: </style>
```

كما ترون لدينا تعريفين للبيانات CSS وكتابة शैली. هل سيكون جيداً إذا أمكننا دمجها وتقلصها

```
   1: <asp:CSSManager runat="server">
```

```
   2:         <link type="text/css" rel="stylesheet" href="~/build/logger/assets/logger.css"/>
```

```
   3:         <link type="text/css" rel="stylesheet" href="../../../build/yuitest/assets/testlogger.css"/>        
```

```
   4:         <style type="text/css">
```

```
   5:         #container, #container2 {
```

```
   6:             width: 400px;
```

```
   7:         }
```

```
   8:  
```

```
   9:         .yui-carousel-element {
```

```
  10:             margin: 0;
```

```
  11:             padding: 0;
```

```
  12:         }
```

```
  13:  
```

```
  14:         .yui-carousel-element li {
```

```
  15:             border: none;
```

```
  16:             margin: 0;
```

```
  17:             padding: 0;
```

```
  18:             width: 100px;
```

```
  19:         }
```

```
  20:         </style>
```

```
  21: </asp:CSSManager>
```

يمكنكم أن تروا في جزء من الأعلى أننا قمنا للتو بتغليف تعريف CSS في &lt;asp:CSSManager&gt;…&lt;/asp:CSSManager&gt; tags…thatM SK1s all there is to it! One other thing , the observer will have noticed that I can now use a MSL4 in the hrefMLS5itMsl6is a nice side effect of this methodMSR7lets you avoid the crazy path traversal stuff MSSL8

من الواضح أن هذا مازال محدوداً قليلاً , لا يعمل ’ لا يشتغل في الثقة الجزئية | , | لا يتعامل مع مجالات متعددة |; | يقول |, | مستوى الموقع CSS | , | سطح الصفحات CSS والصفحات الرئيسية حيث تريد |مسك7 | العديد من الأوراق ذات المحتويات المختلفة | مSK8 | الخطة هي أن نستمر في العمل على هذا لفترة قصيرة | المSK9 | لذا سأقوم تقريباً بحديث هذا قريباً |

Source follows…

```
   1: using System;
```

```
   2: using System.Collections.Generic;
```

```
   3: using System.ComponentModel;
```

```
   4: using System.Text;
```

```
   5: using System.Web.UI;
```

```
   6: using System.Web.UI.HtmlControls;
```

```
   7: using System.IO;
```

```
   8: using System.Security.Cryptography;
```

```
   9: using Yahoo.Yui.Compressor;
```

```
  10:  
```

```
  11: namespace CSSManager
```

```
  12: {
```

```
  13:     [DefaultProperty("Text")]
```

```
  14:     [ToolboxData("<{0}:CSSManager runat=server></{0}:CSSManager>")]
```

```
  15:  
```

```
  16:     [ParseChildren(true, "cssFiles")]
```

```
  17:     public class CSSManager : Control, INamingContainer
```

```
  18:     {
```

```
  19:  
```

```
  20:         public const string FILE_PATH = "~/OutputCSS/{0}.css";
```

```
  21:  
```

```
  22:         public CSSManager() { }
```

```
  23:  
```

```
  24:         public List<HtmlGenericControl> CSSFiles
```

```
  25:         {
```

```
  26:             get;
```

```
  27:             set;
```

```
  28:         }
```

```
  29:  
```

```
  30:  
```

```
  31:         private StringBuilder combinedSheets = new StringBuilder();
```

```
  32:  
```

```
  33:         public string GetStyleSheet(string virtualPath)
```

```
  34:         {
```

```
  35:             string filePath = Context.Server.MapPath(virtualPath);
```

```
  36:             if (!string.IsNullOrEmpty(filePath))
```

```
  37:             {
```

```
  38:                 return File.ReadAllText(filePath);
```

```
  39:             }
```

```
  40:             return string.Empty;
```

```
  41:  
```

```
  42:         }
```

```
  43:  
```

```
  44:         public string CalculateFileHash(string filePaths)
```

```
  45:         {
```

```
  46:             MD5CryptoServiceProvider csp = new MD5CryptoServiceProvider();
```

```
  47:             byte[] pathBytes = csp.ComputeHash(System.Text.UTF8Encoding.UTF8.GetBytes(filePaths));
```

```
  48:             return BitConverter.ToUInt64(pathBytes, 0).ToString();
```

```
  49:  
```

```
  50:         }
```

```
  51:  
```

```
  52:         public void WriteFile(string textToWrite, string fileHash)
```

```
  53:         {
```

```
  54:             File.WriteAllText(Context.Server.MapPath(string.Format(FILE_PATH, fileHash)), textToWrite);
```

```
  55:         }
```

```
  56:  
```

```
  57:         public string CreateDatedFilePath(string filePath)
```

```
  58:         {
```

```
  59:             FileInfo fi = new FileInfo(Context.Server.MapPath(filePath));
```

```
  60:             if (fi.Exists)
```

```
  61:             {
```

```
  62:                 return fi.LastWriteTimeUtc.Ticks.ToString() + "#" + filePath;
```

```
  63:             }
```

```
  64:             return string.Empty;
```

```
  65:  
```

```
  66:  
```

```
  67:         }
```

```
  68:  
```

```
  69:         protected override void CreateChildControls()
```

```
  70:         {
```

```
  71:  
```

```
  72:             if (this.DesignMode == true)
```

```
  73:             {
```

```
  74:                 foreach (var file in CSSFiles)
```

```
  75:                 {
```

```
  76:                     string rel = file.Attributes["rel"];
```

```
  77:  
```

```
  78:                     string href = file.Attributes["href"];
```

```
  79:  
```

```
  80:                     if (rel.ToLowerInvariant() == "stylesheet")
```

```
  81:                     {
```

```
  82:                         file.Attributes["href"] = this.ResolveClientUrl(Context.Server.MapPath(href));
```

```
  83:                         this.Controls.Add(file);
```

```
  84:                     }
```

```
  85:  
```

```
  86:                 }
```

```
  87:             }
```

```
  88:             StringBuilder filePaths = new StringBuilder();
```

```
  89:             int i = 0;
```

```
  90:             foreach (var file in CSSFiles)
```

```
  91:             {
```

```
  92:                 string tagName = file.TagName.ToLowerInvariant();
```

```
  93:                 if (tagName == "link")
```

```
  94:                 {
```

```
  95:                     string rel = file.Attributes["rel"];
```

```
  96:                     string href = file.Attributes["href"];
```

```
  97:  
```

```
  98:                     if (rel.ToLowerInvariant() == "stylesheet")
```

```
  99:                     {
```

```
 100:                         string styleSheet = GetStyleSheet(href);
```

```
 101:                         if (!string.IsNullOrEmpty(styleSheet))
```

```
 102:                             combinedSheets.Append(styleSheet);
```

```
 103:                         filePaths.AppendFormat("{0}#", CreateDatedFilePath(href));
```

```
 104:                     }
```

```
 105:                 }
```

```
 106:                 else if (tagName == "style")
```

```
 107:                 {
```

```
 108:                     string inner = file.InnerHtml;
```

```
 109:                     combinedSheets.Append(inner);
```

```
 110:                     filePaths.Append("CSSSTYLE_" + i);
```

```
 111:                     i++;
```

```
 112:                 }
```

```
 113:  
```

```
 114:             }
```

```
 115:             string minimizedStyles = CssCompressor.Compress(combinedSheets.ToString(), 0, CssCompressionType.Hybrid);
```

```
 116:             string fileHash = CalculateFileHash(filePaths.ToString());
```

```
 117:             WriteFile(minimizedStyles, fileHash);
```

```
 118:  
```

```
 119:             HtmlGenericControl gen = new HtmlGenericControl();
```

```
 120:             gen.TagName = "link";
```

```
 121:             gen.Attributes.Add("href", this.ResolveClientUrl(string.Format(FILE_PATH, fileHash)));
```

```
 122:             gen.Attributes.Add("rel", "stylesheet");
```

```
 123:             this.Controls.Add(gen);
```

```
 124:         }
```

```
 125:  
```

```
 126:     }
```

```
 127: }
```