يعمل حظر التجزئة على تقسيم مربّع على مستوى حظر CSS (مثل قسم أو فقرة) إلى أجزاء متعدّدة عندما لا يظهر كاملاً في حاوية جزء واحدة، ويُسمّى مقسّم. إنّ أداة القطع ليست عنصرًا، بل تمثّل عمودًا في تنسيق متعدد الأعمدة أو صفحة في الوسائط المفصّلة.
ولكي يحدث التجزئة، يجب أن يكون المحتوى ضمن سياق التجزئة. غالبًا ما يتم إنشاء سياق التجزئة من خلال حاوية متعددة الأعمدة (ينقسم المحتوى إلى أعمدة) أو عند الطباعة (يتم تقسيم المحتوى إلى صفحات). قد تحتاج الفقرة الطويلة التي تحتوي على العديد من الأسطر إلى تقسيمها إلى أجزاء متعددة، بحيث يتم وضع الأسطر الأولى في الجزء الأول، ويتم وضع الأسطر المتبقية في الأجزاء اللاحقة.
تشبه عملية تقسيم المحتوى إلى وحدات نوعًا آخر معروفًا من التجزئة، وهو تقسيم المحتوى إلى أسطر، ويُعرف ذلك أيضًا باسم "تقسيم السطر". يمكن تقسيم أي عنصر مضمّن يتألّف من أكثر من كلمة واحدة (أيّ عقدة نصية أو أيّ عنصر <a>
وما إلى ذلك) ويسمح بفاصل سطر إلى أجزاء متعددة. يتم وضع كل جزء في مربع سطر مختلف. مربّع السطر هو عملية تقسيم مضمّنة مكافئة لعنصر القطع للأعمدة والصفحات.
تجزئة وحدات LayoutNG
LayoutNGBlockFragmentation هي إعادة كتابة لمحرّك التجزئة في LayoutNG، وتم طرحها في البداية في الإصدار 102 من Chrome. من حيث بنى البيانات، تم استبدال بنى بيانات متعددة من الإصدارات السابقة بـ شرائح الإصدار الجديد التي يتم تمثيلها مباشرةً في شجرة الشرائح.
على سبيل المثال، نتيح الآن استخدام القيمة avoid (تجنُّب) لخصائص CSS break-before وbreak-after، ما يسمح للمؤلفين بتجنُّب الفواصل مباشرةً بعد العنوان. غالبًا ما يبدو الأمر محرجًا عندما يكون آخر شيء على الصفحة هو العنوان، بينما يبدأ محتوى القسم من الصفحة التالية. من الأفضل إضافة فاصل قبل العنوان.
يتيح Chrome أيضًا تجاوز التجزئة، بحيث لا يتم تقسيم المحتوى الموحّد (المُفترَض أن يكون غير قابل للكسر) إلى أعمدة متعددة، ويتم تطبيق تأثيرات الطلاء بشكل صحيح، مثل الظلال والتحويلات.
اكتملت الآن عملية حظر التقسيم في LayoutNG
تم تضمين التجزئة الأساسية (حاويات الكتل، بما في ذلك تنسيق السطر والعناصر العائمة والموضع خارج التدفق) في الإصدار 102 من Chrome. تم طرح ميزة "التقسيم المرن" وشبكة البيانات في الإصدار 103 من Chrome، وتم طرح ميزة "تقسيم الجدول" في الإصدار 106 من Chrome. أخيرًا، تم طرح ميزة الطباعة في الإصدار 108 من Chrome. كانت ميزة "تقسيم الوحدات" هي الميزة الأخيرة التي كانت تعتمد على المحرّك القديم لتنفيذ التنسيق.
اعتبارًا من الإصدار 108 من Chrome، لم يعُد يتم استخدام المحرّك القديم لتنفيذ التنسيق.
بالإضافة إلى ذلك، تتيح هياكل بيانات LayoutNG الطلاء واختبار النتائج، ولكننا نعتمد على بعض هياكل البيانات القديمة لواجهات برمجة التطبيقات JavaScript التي تقرأ معلومات التنسيق، مثل offsetLeft
وoffsetTop
.
سيتيح لك استخدام LayoutNG في كل العناصر تنفيذ ميزات جديدة لا تتضمّن سوى عمليات تنفيذ LayoutNG (ولا تتضمّن أي ميزات مشابهة في المحرّك القديم)، مثل طلبات البحث عن حاويات CSS وتحديد موضع العنصر الأساسي وMathML والتنسيق المخصّص (Houdini). بالنسبة إلى طلبات البحث عن الحاويات، تم طرحها مبكرًا قليلاً مع تحذير للمطوّرين بأنّ الطباعة غير متاحة بعد.
طرحنا الجزء الأول من LayoutNG في عام 2019، والذي يتألف من تنسيق حاويات الكتل العادية والتنسيق المضمّن والعناصر العائمة والموضع خارج التدفق، ولكن لا يتيح استخدام التنسيقات المرنة أو الشبكية أو الجداول، ولا يتيح تقسيم الكتل على الإطلاق. سنعود إلى استخدام محرّك التنسيق القديم للعناصر المرنة والشبكات والجداول، بالإضافة إلى أيّ عنصر يتضمّن تقسيمًا إلى أجزاء. وينطبق ذلك أيضًا على العناصر المركّبة والعناصر المضمّنة والعناصر العائمة والعناصر خارج مسار العرض ضمن المحتوى المجزّأ. وكما يمكنك أن تتخيل، فإنّ ترقية محرك تصميم معقد كهذا في مكانه هو عملية دقيقة جدًا.
علاوة على ذلك، وبحلول منتصف عام 2019، كانت معظم الوظائف الأساسية لتخطيط تقسيم الكتل في LayoutNG قد نُفذت بالفعل (خلف العلامة). لماذا استغرق الشحن وقتًا طويلاً؟ الإجابة المختصرة هي: يجب أن تتعايش عملية التجزئة بشكل صحيح مع الأجزاء القديمة المختلفة من النظام، والتي لا يمكن إزالتها أو ترقيتها إلى أن تتم ترقية جميع التبعيات.
التفاعل مع محرّك البحث القديم
لا تزال هياكل البيانات القديمة مسؤولة عن واجهات برمجة تطبيقات JavaScript التي تقرأ معلومات التنسيق، لذا علينا إعادة كتابة البيانات إلى المحرّك القديم بطريقة يفهمها. ويشمل ذلك تعديل هياكل البيانات القديمة متعددة الأعمدة، مثل LayoutMultiColumnFlowThread، بشكل صحيح.
رصد ومعالجة المحتوى الاحتياطي في المحرّك القديم
كان علينا الرجوع إلى محرّك التنسيق القديم عندما كان هناك محتوى داخله لا يمكن التعامل معه بعد من خلال تجزئة كتل LayoutNG. عند تنفيذ عملية تقسيم كتلة LayoutNG الأساسية، كانت الشبكة تشمل المرونة والشبكة والجداول وأي محتوى مطبوع. كان هذا الأمر صعبًا بشكل خاص لأنّنا احتجنا إلى رصد الحاجة إلى العناصر الاحتياطية القديمة قبل إنشاء العناصر في شجرة التنسيق. على سبيل المثال، كان علينا رصد ذلك قبل معرفة ما إذا كان هناك عنصر حاوية متعدّد الأعمدة، وقبل معرفة عقد DOM التي ستصبح سياق تنسيق أو لا. هذه مشكلة متداخلة لا تتوفّر لها حلول مثالية، ولكن طالما أنّ السلوك السيئ الوحيد هو النتائج الإيجابية الزائفة (الرجوع إلى التصميم القديم عندما لا يكون هناك حاجة فعلية)، لا بأس بذلك، لأنّ أي أخطاء في سلوك التنسيق هذا هي أخطاء سبق أن واجهها Chromium، وليست أخطاء جديدة.
جولة في الأشجار قبل الطلاء
نُجري عملية ما قبل الطلاء بعد التصميم، ولكن قبل الطلاء. يكمن التحدي الرئيسي في أنّنا ما زلنا بحاجة إلى التنقّل في شجرة عناصر التنسيق، ولكن لدينا الآن أجزاء NG، فكيف نتعامل مع ذلك؟ ننتقل في الوقت نفسه إلى كلّ من عنصر التنسيق وأشجار المقاطع في تنسيق NG. وهذا الأمر معقّد للغاية، لأنّ عملية الربط بين الشجرتَين ليست بسيطة.
على الرغم من أنّ بنية شجرة كائن التنسيق تشبه إلى حد كبير بنية شجرة DOM، فإنّ شجرة الأجزاء هي ناتج التنسيق، وليس إدخالًا له. بالإضافة إلى أنّ شجرة الأجزاء تعكس تأثير أيّ تقسيم، بما في ذلك التقسيم المضمّن (أجزاء السطور) والتقسيم على مستوى الكتل (أجزاء الأعمدة أو الصفحات)، فإنّها تتضمّن أيضًا علاقة مباشرة بين العنصر الرئيسي والعنصر الفرعي بين الكتلة التي تحتوي على العنصر والناشئين عن نموذج DOM الذين يتضمّنون هذا الجزء ككتلة تحتوي عليهم. على سبيل المثال، في شجرة الأجزاء، يكون الجزء الذي تم إنشاؤه بواسطة عنصر تم وضعه بشكل مطلق هو عنصر فرعي مباشر لجزء الكتلة الذي يحتوي عليه، حتى إذا كانت هناك عقد أخرى في سلسلة السلف بين العنصر الفرعي الذي تم وضعه خارج النطاق والكتلة التي يحتوي عليها.
ويمكن أن يكون الأمر أكثر تعقيدًا عندما يكون هناك عنصر تم وضعه خارج مسار التدفق داخل عملية التجزئة، لأنّ الأجزاء خارج مسار التدفق تصبح بعد ذلك عناصر ثانوية مباشرة لوحدة التجزئة (وليست عنصرًا لما تعتقده CSS أنّه الكتلة التي تحتوي على العنصر). كان من الضروري حلّ هذه المشكلة لكي يتوافق المحرّك الجديد مع المحرّك القديم. في المستقبل، من المفترض أن نتمكّن من تبسيط هذا الرمز البرمجي، لأنّ LayoutNG مصمّم لإتاحة جميع أوضاع التنسيق الحديثة بشكلٍ مرن.
المشاكل المتعلّقة بمحرك التجزئة القديم
إنّ المحرّك القديم، الذي تم تصميمه في حقبة سابقة من الويب، لا يتضمّن مفهوم التجزئة، حتى لو كان التجزئة متوفّرًا من الناحية الفنية في ذلك الوقت أيضًا (لإتاحة الطباعة). كان إتاحة استخدام المقاطع مجرد ميزة تم إضافتها لاحقًا (للطباعة) أو تم تعديلها لاحقًا (للأعمدة المتعددة).
عند عرض المحتوى القابل للتقسيم، يعرض المحرّك القديم كل المحتوى في شريط طويل يكون عرضه هو الحجم المضمّن لعمود أو صفحة، ويكون ارتفاعه بالقدر الذي يحتاجه لكي يتضمّن المحتوى. لا يتم عرض هذا الشريط الطويل على الصفحة، بل يتم عرضه على صفحة افتراضية يتم ترتيبها بعد ذلك للعرض النهائي. يشبه ذلك من الناحية المفاهيمية طباعة مقالة كاملة في صحيفة ورقية في عمود واحد، ثم استخدام مقص لتقطيعها إلى عدة أجزاء كخطوة ثانية. (في السابق، كانت بعض الصحف تستخدم أساليب مشابهة لهذا الأسلوب).
يتتبّع المحرّك القديم حدودًا خيالية للصفحات أو الأعمدة في الشريط. ويتيح ذلك للتطبيق دفع المحتوى الذي لا يناسب الحدود إلى الصفحة أو العمود التالي. على سبيل المثال، إذا كان النصف العلوي من السطر فقط يناسب ما يعتقد المحرّك أنّه الصفحة الحالية، سيُدرج "عمود تقسيم الصفحات" لدفعه إلى أسفل الموضع الذي يفترضه المحرّك أنّه أعلى الصفحة التالية. بعد ذلك، يتم تنفيذ معظم عمل التجزئة الفعلي (أي "القطع بالمقصّ والوضع") بعد التنسيق أثناء مرحلة ما قبل الطباعة والطباعة، وذلك من خلال تقسيم الشريط الطويل من المحتوى إلى صفحات أو أعمدة (من خلال اقتصاص الأجزاء وترجمتها). وقد أدّى ذلك إلى استحالة تنفيذ بعض الإجراءات، مثل تطبيق عمليات التحويل والوضع النسبي بعد التجزئة (وهو ما تتطلّبه المواصفات). بالإضافة إلى ذلك، على الرغم من توفّر بعض التوافق مع تقسيم الجدول في المحرّك القديم، لا يتوفّر أي توافق مع تقسيم الشبكة أو الجدول المرن على الإطلاق.
في ما يلي توضيح لكيفية تمثيل تخطيط مكون من ثلاثة أعمدة داخليًا في المحرك القديم، قبل استخدام المقص والموضع والغراء (لدينا ارتفاع محدد بحيث لا يتلاءم سوى أربعة أسطر، ولكن هناك مساحة زائدة في الجزء السفلي):
وبما أنّ محرّك التنسيق القديم لا يقسّم المحتوى أثناء التنسيق، تظهر العديد من العناصر الغريبة، مثل تطبيق موضع نسبي وعمليات تحويل بشكل غير صحيح، واقتصاص ظلال المربّعات عند حواف الأعمدة.
إليك مثال على ظل النص:
لا يتعامل المحرك القديم مع هذا الأمر بشكل جيد:
هل ترى كيف يتم اقتصاص ظل النص من السطر في العمود الأول، ووضعه بدلاً من ذلك أعلى العمود الثاني؟ ويعود سبب ذلك إلى أنّ محرّك التنسيق القديم لا يفهم التجزئة.
من المفترض أن يظهر على النحو التالي:
بعد ذلك، لنجعل الأمر أكثر تعقيدًا، باستخدام التحويلات وظل المربع. لاحظ كيف أنّ محرّك الإعلانات القديم يعرض اقتصاصًا غير صحيح ومحتوى يتجاوز حدود العمود. ويعود السبب في ذلك إلى أنّه من المفترض أن يتم تطبيق عمليات التحويل وفقًا للمواصفات كتأثير بعد التنسيق وبعد التجزئة. يعمل كل من التجزئة LayoutNG بشكل صحيح. ويؤدي ذلك إلى زيادة إمكانية التشغيل التفاعلي مع Firefox، الذي كان يتمتع بدعم جيد للانقسام لبعض الوقت، مع اجتياز معظم الاختبارات في هذا المجال أيضًا.
يواجه المحرّك القديم أيضًا مشاكل في المحتوى الطويل غير المتعدّد الأجزاء. يكون المحتوى متكاملاً إذا لم يكن مؤهلاً لتقسيمه إلى أجزاء متعددة. تكون العناصر التي تتضمّن ميزة التمرير الفائض مصمّمة بشكل موحّد، لأنّه لا يُجدي نفعًا للمستخدمين التمرير في منطقة غير مستطيلة. تعد مربعات الخطوط والصور أمثلة أخرى على المحتوى المتجانس. وفي ما يلي مثال لذلك:
إذا كان جزء المحتوى المتجانس طويلاً للغاية بحيث لا يناسب عمودًا ما، فسيقطعه المحرك القديم بوحشية (مما يؤدي إلى سلوك "مثير للاهتمام" للغاية عند محاولة تمرير الحاوية القابلة للتمرير):
بدلاً من السماح لها بالخروج عن حدود العمود الأول (كما يحدث عند تجزئة وحدات LayoutNG):
يتيح المحرّك القديم استخدام الفواصل التي يتم فرضها. على سبيل المثال، ستُدرج السمة <div style="break-before:page;">
فاصل صفحة قبل علامة DIV. ومع ذلك، فهي تدعم فقط العثور على الفواصل المثلى غير المفروضة. وهو يتيح أيضًا استخدام break-inside:avoid
والأرامل والأرامل، غير أنّه لا يتيح مثلاً تجنُّب الفواصل بين القطع، إذا تم طلبها عبر break-before:avoid
. اطلع على هذا المثال:
في هذا المثال، يتوفّر لعنصر #multicol
مساحة لعرض 5 أسطر في كل عمود (لأنّ ارتفاعه 100 بكسل وارتفاع السطر 20 بكسل)، لذا يمكن أن يتضمّن العمود الأول كل #firstchild
. ومع ذلك، يحتوي العنصر الشقيق #secondchild
على break-before:avoid، ما يعني أنّ المحتوى يريد عدم حدوث فاصل بينهما. بما أنّ قيمة widows
هي 2، نحتاج إلى دفع سطرَين من #firstchild
إلى العمود الثاني لتلبية جميع طلبات تجنُّب الاستراحة. Chromium هو محرك المتصفح الأول الذي يتوافق بشكل كامل مع هذه المجموعة من الميزات.
آلية عمل "التقسيم الجديد"
يُعدّ محرك تنسيق NG بشكل عام المستند من خلال التنقّل في شجرة مربّعات CSS من الأعلى إلى الأسفل. عند ترتيب جميع العناصر الفرعية للعقدة، يمكن إكمال تنسيق هذه العقدة من خلال إنشاء NGPhysicalFragment والعودة إلى خوارزمية تنسيق العنصر الرئيسي. تضيف هذه الخوارزمية الجزء إلى قائمة الأجزاء الفرعية الخاصة بها، وبمجرد إكمال جميع العناصر الثانوية، تنشئ جزءًا لنفسها يحتوي على جميع الأجزاء الفرعية بداخله. وباستخدام هذه الطريقة، يتم إنشاء شجرة أجزاء للمستند بأكمله. هذا تبسيط مفرط، على سبيل المثال، يجب أن تنتقل العناصر التي تم وضعها خارج مسار العرض من مكانها في شجرة DOM إلى الكتلة التي تحتوي عليها قبل أن يتم عرضها. سأتجاهل هذه التفاصيل المتقدّمة هنا من أجل البساطة.
بالإضافة إلى مربّع CSS نفسه، يوفّر LayoutNG مساحة قيودًا لخوارزمية التنسيق. يقدّم ذلك للخوارزمية معلومات مثل المساحة المتوفّرة للتنسيق، وما إذا تمّ إنشاء سياق تنسيق جديد، ونتائج تصغير الهوامش الوسيطة الناتجة عن المحتوى السابق. تعرف مساحة القيد أيضًا حجم الكتلة المخطط للجزء المجزأ، وإزاحة الكتلة الحالية فيه. يشير ذلك إلى مكان الفاصل.
عند استخدام ميزة تجزئة الكتل، يجب أن يتوقف تنسيق العناصر الفرعية عند الفاصل. تشمل أسباب الفواصل نفاذ المساحة في الصفحة أو العمود، أو الفواصل القسرية. بعد ذلك، نُنشئ أجزاء للعقد التي زرناها، ونعود إلى الجذر في سياق التجزئة (حاوية الأعمدة المتعددة أو جذر المستند في حال الطباعة). بعد ذلك، في جذر سياق التجزئة، نستعد لإنشاء أداة تجزئة جديدة وننزل إلى الشجرة مرة أخرى، ونستأنف من حيث توقفنا قبل الفاصل.
تُعرف بنية البيانات الأساسية التي توفّر وسائل استئناف التنسيق بعد الفاصل باسم NGBlockBreakToken. يحتوي على جميع المعلومات اللازمة لاستئناف التخطيط بشكل صحيح في الجزء التالي. يكون رمز NGBlockBreakToken مرتبطًا بعقدة، ويشكّل شجرة NGBlockBreakToken، بحيث يتم تمثيل كل عقدة يجب استئنافها. يتم إرفاق رمز NGBlockBreakToken بعنصر NGPhysicalBoxFragment الذي تم إنشاؤه للعقد التي تنقسم إلى أجزاء. يتم نشر الرموز المميّزة للفاصل إلى العناصر الرئيسية، ما يشكّل شجرة من الرموز المميّزة للفاصل. إذا احتجنا إلى إجراء فاصل قبل عقدة (بدلاً من داخلها)، لن يتم إنشاء أيّ جزء، ولكن لا يزال على العقدة الرئيسية إنشاء رمز فاصل "فاصل قبل" للعقدة، حتى نتمكّن من البدء في عرضها عند الوصول إلى الموضع نفسه في شجرة العقد في أداة تجميع الأجزاء التالية.
يتم إدراج الفواصل عندما تنفد مساحة الفاصل الإعلاني (فاصل غير إلزامي) أو عند طلب فاصل إلزامي.
هناك قواعد في المواصفات لتحديد الفواصل غير المُجبرة المثلى، وليست عملية إدراج فاصل في المكان الذي تنفد فيه المساحة هي الخيار الصحيح دائمًا. على سبيل المثال، هناك خصائص مختلفة في CSS مثل break-before
تؤثر في اختيار موضع الفاصل.
أثناء التنسيق، لتنفيذ قسم مواصفات الفاصلات غير الإجبارية بشكل صحيح، علينا تتبُّع نقاط التوقف المحتملة الجيدة. يعني هذا السجلّ أنّه يمكننا الرجوع واستخدام آخر نقطة توقف ممكنة تم العثور عليها، إذا نفدت المساحة في نقطة نخالف فيها طلبات تجنُّب الفواصل (على سبيل المثال، break-before:avoid
أو orphans:7
). تحصل كل نقطة توقف محتملة على نتيجة، تتراوح بين "لا تفعل ذلك إلا كحل أخير" و"مكان مثالي للتوقف"، مع بعض القيم بينهما. إذا حصل موضع الفاصل على تقييم "مثالي"، يعني ذلك أنّه لن يتم انتهاك أي من قواعد الفواصل إذا وضعنا الفاصل هناك (وإذا حصلنا على هذا التقييم في النقطة التي تنفد فيها المساحة تمامًا، لن يكون هناك حاجة إلى البحث عن موضع أفضل). إذا كانت النتيجة هي "المنتج الأخير"، تكون نقطة التوقف ليست صالحة، ولكننا قد نقطعها إذا لم نجد أي شيء أفضل، وذلك لتجنب تجاوز الأجزاء المجزّأة.
لا تحدث نقاط التوقف الصالحة بشكل عام إلا بين العناصر الشقيقة (مربّعات الخطوط أو الكتل)، وليس مثلاً بين العنصر الرئيسي وأول عنصر فرعي له (نقاط التوقف من الفئة C هي استثناء، ولكن لا نحتاج إلى مناقشتها هنا). تتوفر نقطة توقف صالحة، على سبيل المثال، قبل عنصر كتلة أخوي مع break-before:avoid، ولكنّها تقع بين "مثالية" و"الخيار الأخير".
أثناء التنسيق، نتتبّع أفضل نقطة توقّف تم العثور عليها حتى الآن في بنية تُسمى NGEarlyBreak. الفاصل المبكر هو نقطة توقف محتملة قبل عقدة كتلة أو داخلها، أو قبل سطر (سواء كان سطر حاوية كتلة أو سطر مرن). قد نُشكّل سلسلة أو مسارًا من عناصر NGEarlyBreak، في حال كانت نقطة التوقف الأفضل في مكان ما في عمق شيء مررنا به سابقًا في الوقت الذي نفد فيه المساحة. وفي ما يلي مثال لذلك:
في هذه الحالة، نفدّت المساحة قبل #second
مباشرةً، ولكنّه يتضمّن "break-before:avoid"، ما يحصل على نتيجة موضع الفاصل "انتهاك avoid break". في هذه المرحلة، لدينا سلسلة NGEarlyBreak من "داخل #outer
> داخل #middle
> داخل #inner
> قبل "السطر 3"'، مع "مثالي"، لذا نفضّل التوقف عند هذا الموضع. لذلك، علينا العودة وإعادة تنفيذ التنسيق من بداية #outer (وهذه المرة تمرير NGEarlyBreak الذي عثرنا عليه)، حتى نتمكّن من الفاصل قبل "السطر 3" في #inner. (يتم وضع الفاصل قبل "السطر 3"، بحيث تنتهي الأسطر الأربعة المتبقية في المُجزئ التالي، وذلك تقديرًا لـ widows:4
).
تم تصميم الخوارزمية بحيث يتم دومًا الوصول إلى أفضل نقطة توقف ممكنة، كما هو موضح في المواصفات، عن طريق تجاهل القواعد بالترتيب الصحيح، وذلك في حال عدم استيفاء جميع القواعد. تجدر الإشارة إلى أنّه يجب إعادة التنسيق مرة واحدة فقط في كل مسار تقسيم. بحلول الوقت الذي ننتقل فيه إلى جولة التنسيق الثانية، يكون قد تمّ نقل أفضل موضع للفاصل إلى خوارزميات التنسيق، وهو موضع الفاصل الذي تمّ اكتشافه في جولة التنسيق الأولى، وتمّ تقديمه كجزء من إخراج التنسيق في تلك الجولة. في الجولة الثانية من تنسيق الصفحة، لا نضع العناصر في الصفحة إلى أن تنفد المساحة، ولكن من المفترض ألا تنفد المساحة (لأنّ ذلك سيؤدي إلى حدوث خطأ)، لأنّنا حصلنا على مكان رائع (أو على الأقلّ كان أفضل مكان متاح) لإدراج فاصل مبكر، وذلك لتجنّب مخالفة أيّ من قواعد الفواصل بدون داعٍ. إذًا، نتطرق إلى هذه النقطة، ونتوقف.
في ضوء ذلك، قد نضطر أحيانًا إلى مخالفة بعض طلبات تجنُّب الفواصل إذا كان ذلك يساعد في تجنُّب تجاوز سعة وحدة التخزين المؤقتة للمقاطع. على سبيل المثال:
في هذه الحالة، نفدَت المساحة قبل #second
مباشرةً، ولكنّها تحتوي على "break-before:avoid". يتم ترجمة ذلك إلى "تجنب الانتهاك بسبب الفواصل"، تمامًا مثل المثال الأخير. لدينا أيضًا NGEarlyBreak مع "انتهاك الأيتام والفقرات التي تنتهي بفاصل" (داخل #first
> قبل "السطر 2")، وهو ما زال غير مثالي، ولكنه أفضل من "انتهاك الفاصل لتجنّب". وبالتالي، سنضع فاصلاً قبل "السطر 2"، ما يخالف طلب استخدام الكلمات المتقطعة. تتناول المواصفة هذه المسألة في 4.4. الفواصل غير الإجبارية، حيث يتم تحديد قواعد الفواصل التي يتم تجاهلها أولاً إذا لم يكن لدينا نقاط توقف كافية لتجنّب تجاوز عدد المقاطع في وحدة التخزين
الخاتمة
كان الهدف الوظيفي من مشروع تجزئة الكتل البرمجية في LayoutNG هو توفير تطبيق يدعم بنية LayoutNG لكل ما يدعمه المحرك القديم، بالإضافة إلى أقل قدر ممكن، باستثناء إصلاحات الأخطاء. ويتمثل الاستثناء الرئيسي في تحسين ميزة تجنُّب الفواصل (break-before:avoid
على سبيل المثال)، لأنّ هذه الميزة هي جزء أساسي من محرّك التجزئة، لذا كان من المفترض أن تكون متوفّرة منذ البداية، لأنّ إضافتها لاحقًا تعني إعادة كتابة أخرى.
والآن بعد أن اكتملت عملية تقسيم مجموعة كتل LayoutNG، يمكننا بدء العمل على إضافة وظائف جديدة، مثل إتاحة أحجام مختلطة للصفحات عند الطباعة، و@page
مربّعات الهوامش عند الطباعة، وbox-decoration-break:clone
والمزيد. وكما هو الحال مع LayoutNG بشكل عام، نتوقّع أن ينخفض معدّل الأخطاء وعبء الصيانة للنظام الجديد بشكل كبير بمرور الوقت.
شكر وتقدير
- Una Kravets على "لقطة الشاشة المصنوعة يدويًا" الرائعة.
- كريس هارلسون لمراجعة النصوص وتقديم الملاحظات والاقتراحات
- Philip Jägenstedt للحصول على الملاحظات والاقتراحات
- راشيل أندرو لتعديل أول مثال على رسم بياني متعدّد الأعمدة