البنية
TailwindPHP منفذ مطابق بنسبة 1:1. تعكس قاعدة الشيفرة بنية TailwindCSS نفسها — أسماء الملفات والتنظيم ذاتها — وتعزل الأجزاء التي لا يمكن نقلها مباشرةً (PHP لا يدعم Rust ولا V8) ضمن src/_tailwindphp/. تعرض هذه الصفحة خط أنابيب التجميع وتخطيط المصدر وإعادة تنفيذ lightningcss والنهج المتبع لتوثيق الاختلافات.
مسار المعالجة
يتألف إنشاء CSS من مراحل متتابعة. لا توجد خطوة بناء منفصلة؛ فكل استدعاء لـ tw::generate() يشغّل خط الأنابيب كاملًا.
CSS input (@import "tailwindcss"; @theme { … })
│
▼
┌──────────────┐
│ Parse CSS │ css-parser.php → ast.php nodes
└──────┬───────┘
▼ design system (theme, utilities, variants)
┌──────────────┐
│ Scan content │ candidate.php — extract class names from HTML
└──────┬───────┘
▼ candidates
┌──────────────┐
│ Compile │ compile.php — candidate → AST, via design-system.php
└──────┬───────┘
▼ AST
┌──────────────┐
│ Optimize │ _tailwindphp/LightningCss.php — nesting, @media, calc()
└──────┬───────┘
▼
┌──────────────┐
│ Serialize │ ast.php toCss() (minified when requested)
└──────┬───────┘
▼
CSS output
التحليل. يقرأ css-parser.php مدخلات CSS — @import و@theme و@utility و@layer والقواعد الخام — ويحوّلها إلى شجرة بنية مجردة من عُقد ast.php (قواعد الأنماط والتوجيهات at-rules والتصريحات). وتُحل في هذه المرحلة توجيهات @import الخاصة بالوحدات الافتراضية (tailwindcss وtailwindcss/preflight …) ومسارات الملفات، ثم تُستبدل.
بناء نظام التصميم. يستخلص theme.php قيم السمة (الألوان والمسافات ونقاط التوقف) من كتل @theme التي جرى تحليلها، إضافةً إلى القيم الافتراضية. وتُعد design-system.php السجل المركزي الذي يربط السمة بعمليات البحث عن الأدوات والمتغيرات المعرفة في utilities.php وvariants.php.
مسح المحتوى. يستخرج candidate.php أسماء الفئات المرشحة من المحتوى الممرر (HTML والقوالب)، ويحلل كل اسم إلى أجزائه — أداة أساسية ومتغيرات ومعدّلات وقيم اعتباطية وعلامة الأهمية.
التجميع. يحوّل compile.php كل اسم مرشح إلى عقد AST بالبحث عنه في نظام التصميم وتطبيق متغيراته ومعدّلاته. وتُهمل الأسماء المرشحة التي لا تطابق أداة فعلية.
التسلسل والتحسين. يتنقل toCss() في ast.php عبر الشجرة (بمساعدة دوال في walk.php) ويصدر سلسلة CSS. وتُطبَّق التحويلات المكافئة لـlightningcss في _tailwindphp/LightningCss.php، بحيث يطابق الناتج ما ينتجه TailwindCSS بعد مرحلة المعالجة اللاحقة في Rust.
التصغير. عند تفعيل minify، يُصدر toCss() شيفرة CSS مصغرة أثناء التسلسل. وتتولى _tailwindphp/CssMinifier.php تمرير سلسلة tw::minify() المستقلة. راجع التخزين المؤقت والتصغير.
تخطيط المصدر
يعكس src/ TailwindCSS. والتغيير البنيوي الوحيد هو أن utilities.ts في TailwindCSS يتجاوز 6,000 سطر، لذا قُسّم إلى src/utilities/ مع ملف لكل فئة لتسهيل الصيانة.
src/
├── _tailwindphp/ # PHP-specific — NOT part of the TailwindCSS port
│ ├── LightningCss.php # CSS transforms (lightningcss Rust library equivalent)
│ ├── CssMinifier.php # CSS minification
│ └── lib/ # Companion library ports (TailwindPHP\Lib\*)
│ ├── clsx/ # clsx port
│ ├── tailwind-merge/ # tailwind-merge port
│ └── cva/ # CVA port
│
├── plugin/ # Plugin system
│ └── plugins/
│ ├── typography-plugin.php # @tailwindcss/typography port
│ └── forms-plugin.php # @tailwindcss/forms port
│
├── utilities/ # Split from TailwindCSS utilities.ts (one file per category)
│ ├── accessibility.php # sr-only, forced-colors
│ ├── backgrounds.php # bg-*, gradient-*, from-*, via-*, to-*
│ ├── borders.php # border-*, rounded-*, divide-*, outline-*
│ ├── effects.php # shadow-*, opacity-*, mix-blend-*
│ ├── filters.php # blur-*, brightness-*, contrast-*, …
│ ├── flexbox.php # flex-*, grid-*, gap-*, justify-*, align-*
│ ├── interactivity.php # cursor-*, scroll-*, touch-*, select-*
│ ├── layout.php # display, position, z-*, overflow-*, …
│ ├── masks.php # mask-linear-*, mask-radial-*, mask-conic-*
│ ├── sizing.php # w-*, h-*, min-*, max-*, size-*
│ ├── spacing.php # m-*, p-*, space-*
│ ├── svg.php # fill-*, stroke-*
│ ├── tables.php # border-collapse, table-layout
│ ├── transforms.php # translate-*, rotate-*, scale-*, skew-*
│ ├── transitions.php # transition-*, duration-*, ease-*, delay-*
│ └── typography.php # font-*, text-*, leading-*, tracking-*
│
├── utils/ # Helper functions (ported from utils/)
│
├── index.php # Main entry — compile(), cn(), variants(), merge(), join()
├── ast.php # AST nodes and toCss()
├── candidate.php # Candidate parsing (class name → parts)
├── compile.php # Candidate to CSS compilation
├── css-functions.php # theme(), --theme(), --spacing(), --alpha()
├── css-parser.php # CSS parsing
├── design-system.php # Central registry for utilities/variants
├── plugin.php # Plugin system (PluginInterface, PluginAPI, PluginManager)
├── theme.php # Theme value resolution
├── utilities.php # Utility registration and lookup
├── value-parser.php # CSS value parsing
├── variants.php # Variant handling (hover, focus, responsive, …)
└── walk.php # AST traversal
ما يعادل lightningcss
يعهد TailwindCSS بمعالجة CSS اللاحقة — التداخل ومعالجة استعلامات الوسائط وتبسيط القيم — إلى lightningcss، وهو محلل ومحوّل ومصغّر مكتوب بـ Rust. لا يستطيع PHP تحميل مكتبة Rust، لذا يعيد src/_tailwindphp/LightningCss.php تنفيذ التحويلات التي يعتمد عليها TailwindPHP فعليًا، وينتج مخرجات مطابقة بايتًا ببايت للحالات التي تغطيها مجموعة الاختبارات.
تشمل التحويلات المؤكدة:
| التحويل | ما يفعله |
|---|---|
| تسطيح التداخل | يحل المحددات & باستخدام قواعد :is(…) المرجعية ويسطح القواعد المتداخلة (handleNesting() في ast.php، وهو نقل لمرحلة TailwindCSS)؛ ويخفض transformNesting مستوى التداخل المتبقي أسفل المستوى الأول الحامل للتصريحات |
| تسطيح قواعد at الشرطية | يسّطح قواعد @media و@supports و@container و@starting-style المتداخلة في مواضعها، مع الحفاظ على ترتيب المصدر، ويدمج الأشقاء المتجاورين مباشرةً فقط إذا كانت شروطهم متطابقة |
| ترتيب التصريحات | يعيد ترتيب التصريحات وفق سلسلة معالجات التصريحات في lightningcss، لتظهر الخصائص بترتيب المرجع (reorderDeclarations) |
تبسيط calc() |
يبسّط تعبيرات calc() (simplifyCalcExpressions) |
| إزالة الصفر البادئ | 0.5 ← .5 (normalizeLeadingZeros) |
| المسافات في دوال التحويل | يوحّد المسافات داخل دوال التحويل (normalizeTransformFunctions) |
| تطبيع قيم الشبكة | يضيف مسافات حول / في قيم الامتداد، ويحوّل الأعداد الصحيحة المجردة إلى px في grid-template-* (normalizeGridValues) |
| تطبيع الألوان | يوحّد صياغة الألوان ويقيّم color-mix() إلى oklab() (normalizeColors، evaluateColorMix) |
| اقتباس URL | url(./x.jpg) ← url("./x.jpg") (normalizeUrlQuoting) |
| بادئات الموردين | إضافة بادئات مكافئة لـ Autoprefixer (addVendorPrefixes) |
هذا الملف معزول عمدًا ضمن _tailwindphp/ وموسوم بـ @port-deviation:replacement — فهو يمثّل اعتمادًا خارجيًا بدلًا من نقل مصدر TailwindCSS.
علامات الانحراف عن النقل
يتضمن كل ملف تنفيذ علامات @port-deviation:* في كتلة التوثيق، توضّح أين ولماذا يختلف تنفيذ PHP عن الأصل في TypeScript. والهدف هو ألا يضطر القارئ الذي يقارن PHP بمصدر TailwindCSS إلى التساؤل عما إذا كان الاختلاف مقصودًا.
| العلامة | المعنى |
|---|---|
@port-deviation:none |
نقل مباشر بنسبة 1:1 دون اختلافات جوهرية |
@port-deviation:async |
يستخدم PHP شيفرة متزامنة بدلًا من async/await |
@port-deviation:storage |
هياكل بيانات مختلفة (مصفوفة PHP مقابل JS Map/Set) |
@port-deviation:types |
تعليقات PHPDoc بدلًا من أنواع TypeScript |
@port-deviation:sourcemaps |
تم حذف تتبع خرائط المصدر |
@port-deviation:enum |
ثوابت PHP بدلًا من تعداد TypeScript |
@port-deviation:errors |
نهج مختلف لمعالجة الأخطاء |
@port-deviation:replacement |
تنفيذ PHP يحل محل مكتبة خارجية (e.g. lightningcss) |
@port-deviation:helper |
مساعد خاص بـ PHP غير موجود في الأصل |
@port-deviation:performance |
تحسين خاص بـ PHP يحافظ على تطابق الناتج |
@port-deviation:omitted |
لم تُنقل الوحدة/الميزة بالكامل (خارج النطاق) |
للاطلاع على علامات @port-deviation:performance وكيفية ضمان التكافؤ، راجع الأداء والاختبارات.