الأسئلة الشائعة حول SmooshGate

ماذا حدث التمهّل؟

اتضح أن اقتراح لميزة لغة JavaScript تُسمى Array.prototype.flatten غير متوافق مع الويب. تسبب شحن الميزة في Firefox Nightly في تعطل موقع ويب شهير واحد على الأقل. وبما أنّ الرموز البرمجية التي تسبب المشكلة هي جزء من مكتبة MooTool واسعة النطاق، من المرجّح أن يتأثر العديد من المواقع الإلكترونية الأخرى. (على الرغم من أن Mootools لا يشيع استخدامه للمواقع الإلكترونية الجديدة في عام 2018، إلا أنه كان مشهورًا جدًا ولا يزال متاحًا على العديد من مواقع الإنتاج الإلكترونية.

اقترح مؤلف الاقتراح على سبيل المزاح إعادة تسمية flatten إلى smoosh لتجنُّب مشكلة التوافق. لم تكن النكتة واضحة للجميع، وبدأ بعض الأشخاص يعتقدون بشكل غير صحيح أنه تم تحديد الاسم الجديد بالفعل، وبالتالي تم تصعيد الأمور بسرعة.

ما هي وظيفة Array.prototype.flatten؟

Array.prototype.flat، الذي تم اقتراحه في الأصل كـ Array.prototype.flatten، يعمل على تنظيم الصفائف بشكل متكرر حتى depth المحدد والتي يتم ضبطها تلقائيًا على 1.

// Flatten one level:
const array = [1, [2, [3]]];
array.flat();
// → [1, 2, [3]]

// Flatten recursively until the array contains no more nested arrays:
array.flat(Infinity);
// → [1, 2, 3]

يتضمن الاقتراح نفسه السمة Array.prototype.flatMap، التي تشبه Array.prototype.map باستثناء أنّها تنظّم النتيجة في صفيف جديد.

[2, 3, 4].flatMap((x) => [x, x * 2]);
// → [2, 4, 3, 6, 4, 8]

ما الذي تفعله Mootools والذي يسبب هذه المشكلة؟

تحدّد Mootools الإصدار غير العادي من Array.prototype.flatten:

Array.prototype.flatten = /* non-standard implementation */;

يختلف تنفيذ flatten في MooTool عن المعيار المقترَح. ومع ذلك، هذه ليست المشكلة! عندما تشحن المتصفحات Array.prototype.flatten بشكل أصلي، تلغي Mootools التنفيذ الأصلي. يضمن ذلك أنّ الرموز البرمجية التي تعتمد على سلوك MooTools تعمل على النحو المطلوب بغض النظر عمّا إذا كانت flatten الأصلية متاحة. كل الأمور جيدة حتى الآن

لسوء الحظ، يحدث شيء آخر بعد ذلك. تنسخ MooTool جميع طرق الصفائف المخصصة إلى Elements.prototype (حيث Elements هي واجهة برمجة تطبيقات خاصة بـ Mootools):

for (var key in Array.prototype) {
  Elements.prototype[key] = Array.prototype[key];
}

تتكرر for-in على السمات "enumerable"، والتي لا تتضمن طرقًا أصلية مثل Array.prototype.sort، ولكنها تتضمن خصائص يتم تحديدها بانتظام مثل Array.prototype.foo = whatever. مع ذلكArray.prototype.sort = whatever

في الوقت الحالي، تنشئ Array.prototype.flatten = mooToolsFlattenImplementation سمة flatten قابلة للتعداد، لذلك يتم نسخها لاحقًا إلى Elements. ولكن إذا شحنت المتصفحات إصدارًا أصليًا من flatten، يصبح هذا الإصدار غير قابل للعد، ولن يتم نسخه إلى Elements. أي رمز يعتمد على Elements.prototype.flatten الخاص بأداة MooTool معطّل الآن.

يبدو أنّ تغيير Array.prototype.flatten الأصلي ليصبح قابلاً للتعداد سيؤدي إلى حلّ المشكلة، ولكن من المحتمل أن يؤدي ذلك إلى حدوث المزيد من مشاكل التوافق. بعد ذلك، سيحصل كل موقع إلكتروني يعتمد على for-in على مصفوفة التكرار (وهو ممارسة سيئة، ولكنه يحدث أحيانًا) سيحصل فجأة على تكرار تكراري إضافي للسمة flatten.

تكمن المشكلة الأساسية الأكبر هنا في تعديل الكائنات المضمنة. يُعد توسيع النماذج الأولية الأصلية ممارسة سيئة في الوقت الحاضر، نظرًا لأنها لا تكتب بشكل جيد مع مكتبات أخرى ورموز خارجية. لا تعدِّل الكائنات التي لا تملكها.

لماذا لا نحتفظ بالاسم الحالي فقط ونكسر الويب؟

في عام 1996، قبل انتشار CSS على نطاق واسع، وقبل وقت طويل من أن يصبح "HTML5" شيئًا، تم إطلاق موقع Space Jam الإلكتروني. اليوم، لا يزال الموقع يعمل بنفس الطريقة التي كان يعمل بها قبل 22 عامًا.

كيف حدث ذلك؟ هل حافظ شخص ما على موقع الويب هذا طوال هذه السنوات، ويتم تحديثه في كل مرة يشحن فيها موردو المتصفح ميزة جديدة؟

لقد اتضح أنّ "عدم تعطّل الويب" هو مبدأ التصميم الأول في HTML وCSS وJavaScript وأي معيار آخر يُستخدم على نطاق واسع على الويب. إذا كان شحن ميزة متصفح جديدة يؤدي إلى توقُّف المواقع الإلكترونية الحالية عن العمل، سيكون هذا سيئًا للجميع:

  • حصول زوّار المواقع الإلكترونية المتأثرة فجأة على تجربة مستخدم معطّلة
  • تحول مالكي مواقع الويب من امتلاك موقع ويب يعمل بشكل مثالي إلى موقع غير فعال دون أن يغيّروا أي شيء؛
  • بائعي المتصفحات الذين يشحنون الميزة الجديدة يخسرون حصة السوق، بسبب تبديل المستخدمين للمتصفح بعد ملاحظة "تعمل في المتصفح X"،
  • فبمجرد معرفة مشكلة التوافق، يرفض موردو المتصفحات الآخرون شحنها. لا تتطابق مواصفات الميزة مع الواقع (" يشمل ذلك عملاً خياليًا")، ما يؤثر سلبًا في عملية توحيد المقاييس.

بالتأكيد، عند النظر إلى الوراء، لم يرتكب MooTool أي خطأ، ولكنه لا يمكن أن يعاقب المستخدمين باختراق الويب، بل يعاقبهم. لا يعرف هؤلاء المستخدمون ما هي أداة moo. بدلاً من ذلك، يمكننا إيجاد حل آخر، ويمكن للمستخدمين مواصلة استخدام الويب. يمكنك الاختيار بسهولة.

هل يعني ذلك أنّه لا يمكن أبدًا إزالة واجهات برمجة التطبيقات السيئة من منصة الويب؟

يعتمد ذلك على بعض العوامل. في حالات نادرة، يمكن أن تتم إزالة الميزات غير الصالحة من الويب. إنّ مجرد معرفة ما إذا كان من الممكن إزالة ميزة ما هو جهد مربك للغاية، إذ يتطلّب قياسًا مكثفًا عن بُعد لتحديد عدد صفحات الويب التي يمكن أن يتغيّر سلوكها. ولكن عندما تكون الميزة غير آمنة بما يكفي أو تكون ضارة للمستخدمين أو نادرًا جدًا ما يتم استخدامها، يمكن القيام بذلك.

<applet> و<keygen> وshowModalDialog() هي أمثلة كلها على واجهات برمجة التطبيقات غير الصالحة التي تمت إزالتها بنجاح من Web Platform.

لمَ لا نكتفي بإصلاح أدوات MooTools؟

ويُعد تصحيح MooTools بحيث لا يتسع للكائنات المضمنة بعد ذلك. ومع ذلك، فإنه لا يحل المشكلة المطروحة. حتى لو كانت MooTool تصدر إصدارًا مصحّحًا، يجب على جميع المواقع الإلكترونية الحالية التي تستخدمها أن يتم تحديثها لتجنب مشكلة التوافق.

ألا يستطيع المستخدمون تعديل نسختهم من Mootools فقط؟

في عالم مثالي، ستصدر MooTool تصحيحًا، ويتم تحديث كل موقع إلكتروني يستخدم MooTool بشكل سحري في اليوم التالي. تم حل المشكلة، أليس كذلك؟!

هذا غير واقعي. حتى إذا حدد شخص ما المجموعة الكاملة من مواقع الويب المتأثرة بطريقة ما، ونجح في العثور على معلومات الاتصال لكل موقع منها، وتواصل بنجاح مع جميع مالكي مواقع الويب، وأقنعهم جميعًا بإجراء التحديث (مما قد يعني إعادة هيكلة قاعدة التعليمات البرمجية بالكامل)، فقد تستغرق العملية بأكملها سنوات، في أحسن الأحوال.

يُرجى العِلم أنّ العديد من هذه المواقع الإلكترونية قديمة ومن المرجّح أنّها لم تخضع للصيانة. حتى إذا كان المشرف لا يزال موجودًا، فمن المحتمل ألا يكون مطور ويب ما إذا كان ماهرًا مثلك. لا يمكننا أن نتوقع أن يذهب الجميع ويغيرون موقع الويب الخاص بهم الذي يبلغ من العمر 8 سنوات بسبب مشكلة في توافق الويب.

كيف تعمل عملية TC39؟

تُعد TC39 اللجنة المسؤولة عن تطوير لغة JavaScript من خلال معيار ECMAScript.

#SmooshGate كان يعتقد أنّ "TC39 يريد إعادة تسمية flatten إلى smoosh" لا يتم أخذ القرارات الرئيسية مثل إعادة تسمية العرض بسهولة، ولا يتخذها شخص واحد، وبالتأكيد لا يتم اتخاذها بين عشية وضحاها بناءً على تعليق GitHub واحد.

يتّبع إطار الشفافية والموافقة TC39 عملية مرحلية واضحة لاقتراحات الميزات. تتم مناقشة اقتراحات ECMAScript وأي تغييرات رئيسية تطرأ عليها (بما في ذلك إعادة تسمية الطرق) خلال اجتماعات TC39، ويجب أن توافق عليها اللجنة بالكامل قبل أن تصبح رسمية. في حالة Array.prototype.flatten، سبق أن مرّ الاقتراح بعدة مراحل من الاتفاق، وصولاً إلى المرحلة 3، ما يشير إلى أنّ الميزة جاهزة للتنفيذ في متصفحات الويب. من الشائع حدوث مشكلات إضافية في المواصفات أثناء التنفيذ. في هذه الحالة، جاءت أهم الملاحظات بعد محاولة شحنها، أي أنّ الميزة بحالتها الراهنة تعطّل الويب. فالمشاكل التي يصعب التنبؤ بها مثل هذه تشكّل جزءًا من سبب عدم انتهاء عملية TC39 بمجرد شحن المتصفّحات لإحدى الميزات.

يعمل إطار الشفافية والموافقة (TC39) على الإجماع، مما يعني أنه على اللجنة الاتفاق على أي تغييرات جديدة. حتى لو كان الاقتراح الجادّ هو smoosh، من المرجَّح أنّ أحد أعضاء اللجنة قد يعترض عليه لصالح اسم أكثر شيوعًا، مثل "compact" أو "chain".

لم يسبق أن تمت مناقشة إعادة التسمية من flatten إلى smoosh (حتى لو لم تكن مزحة) في اجتماع إطار الشفافية والموافقة. ومن ثم، فإن الموقف الرسمي لإطار الشفافية والموافقة TC39 بشأن هذا الموضوع غير معروف حاليًا. لا يمكن لأي فرد واحد التحدث بالنيابة عن جميع المشاركين في إطار الشفافية والموافقة حتى يتم التوصل إلى توافق في الآراء في الاجتماع التالي.

يشارك عادةً أشخاص ذوو خلفيات متنوعة للغاية اجتماعات TC39، فبعضهم يتمتع بسنوات من الخبرة في تصميم لغات البرمجة، ويعمل الآخرون على متصفح أو محرك JavaScript، وهناك عدد متزايد من الحاضرين لتمثيل منتدى مطوّري JavaScript.

كيف تم حل SmooshGate، في النهاية؟

خلال اجتماع TC39 في أيار (مايو) 2018، تم حلّ #SmooshGate رسميًا من خلال إعادة تسمية flatten إلى flat.

يتم شحن Array.prototype.flat وArray.prototype.flatMap في الإصدارين 8.9 وChrome 69.