Jsdom: تنفيذ innerText

تم إنشاؤها على ٢٥ سبتمبر ٢٠١٥  ·  26تعليقات  ·  مصدر: jsdom/jsdom

jsdom هي أداة رائعة لكشط الويب. ومع ذلك ، فإن textContent طريقة غير ملائمة للغاية للحصول على نص مقروء لتحويل النص إلى html2text.

هناك مقال رائع عن فائدة استخدام innerText ضئيل في كثير من الحالات:

http://perfectionkills.com/the-poor-misunderstood-innerText/

يقترح المؤلف getSelection().toString() كحل بديل بطيء جدًا ، لكن getSelection لم يتم تنفيذه في jsdom حتى الآن.

هل يمكنك التفكير في تنفيذ innerText في jsdom ؟ قام المؤلف باستكشاف رائع حول هذا الموضوع ، حتى أنه أضاف مواصفات بسيطة في النهاية.

feature layout

التعليق الأكثر فائدة

في حالة تعرض أي شخص آخر لهذه المشكلة ، فقد اتخذت خطوة واحدة إلى الأمام واستخدمت الحزمة sanitize-html للحصول على ما يفعله المتصفح بشكل أساسي (لاحظ أنني لم أستورد إعداد JSDOM لأنني وجدت أنه لم يكن ضروريًا عند وضع هذا في ملف إعداد Jest الخاص بي ولكن إذا كنت لا تستخدم Jest ، فأنت تريد استخدام الإعداد global.Element = (new JSDOM()).window.Element الذي أوصى bennypowers ):

Object.defineProperty(global.Element.prototype, 'innerText', {
  get() {
    return sanitizeHtml(this.textContent, {
      allowedTags: [], // remove all tags and return text content only
      allowedAttributes: {}, // remove all tags and return text content only
    });
  },
  configurable: true, // make it so that it doesn't blow chunks on re-running tests with things like --watch
});

ال 26 كومينتر

ويا للأسف أن مكتبة Selection و innerText ليست متوافقة مع jsdom : https://github.com/timdown/rangy/issues/348

لذا ، فإن innerText ليس قياسيًا ، ولم يتم تنفيذه في محرك رئيسي واحد على الأقل (Firefox). بدون معيار ، لا أعتقد أننا يجب أن نطبقه.

يبدو أن هناك بعض الحركة في هذا الأمر برمته مع مسودة المواصفات هنا . انظر أيضا كل المراجع . لا توجد مشكلات في الريبو ، لذلك أتساءل عن مدى اكتماله بالفعل / مدى سرعة التقدم.

من المواصفات ، يبدو أننا لا نستطيع تنفيذ innerText بشكل صحيح بدون دعم التخطيط الأساسي.

نعم ، لن يكون هذا حقًا قابلاً للتنفيذ في jsdom على أي حال ، بدون الكثير من أعمال البنية التحتية ... لا أحد يرفع آماله :(.

فيما يتعلق بمتطلبات دعم التخطيط: https://github.com/rocallahan/innerText-spec/issues/2

هل هناك أي خطة لتنفيذه بسبب اعتماد WHATWG؟

نعم ... على الرغم من أن المواصفات تتطلب الكثير من الأشياء التي لا يمتلكها jsdom ، حول مربعات CSS :(. لست متأكدًا مما يجب فعله.

هل هناك أي ليب لهذا لتوصيله مع jsdom؟

domenic Care لإسقاط بعض المعرفة حول سبب إجراء مثل هذا الإصلاح الشامل للبنية التحتية؟ كنا نظن أن الغوريلا التي يبلغ وزنها 800 رطل في الغرفة ستترك المفتاح الصغير. لكن يبدو أنها لن تسير في أي مكان. كما تعلم ، تم لف رأسي حول أحشاء jsdom. أين سيكون مكانًا رائعًا في الريبو لبدء مراجعة التعليمات البرمجية إلى jsdom newb؟

شكرا مقدما 🙏 / ccvsemozhetbyt

المشكلة الأساسية هي حقيقة أن innerText يعتمد على محرك التخطيط للإرشاد ، و jsdom ليس لديه محرك تخطيط. راجع https://html.spec.whatwg.org/multipage/dom.html#the -innertext-idl-attribute و
http://perfectionkills.com/the-poor-misunderstood-innerText/ . من الرابط الثاني:

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

لا يزال خارج النطاق وليس هناك حل بديل؟

يبدو أن المواصفات تقول:

إذا لم يتم تقديم هذا العنصر ، أو إذا كان وكيل المستخدم هو وكيل مستخدم لا يتبع CSS ، فقم بإرجاع [التشديد مضاف] ثم إرجاع نفس القيمة مثل سمة textContent IDL على هذا العنصر.

أعتقد أن الحل هو إرجاع textContent .

نحن نطبق ما يكفي من CSS التي لا أعتقد أن ذلك ينطبق. نحن فقط لا ننفذ أجزاء التخطيط ...

مرحبا شباب ، أي أخبار عن هذا؟

فقط استخدم الكروم مقطوعة الرأس :)

domenic من تلك المواصفات التي ذكرها coreh :
https://html.spec.whatwg.org/multipage/dom.html#the -innertext-idl-attribute

إذا لم يتم عرض هذا العنصر ، أو إذا كان وكيل المستخدم وكيل مستخدم بخلاف CSS ، فقم بإرجاع نفس القيمة مثل السمة textContent IDL على هذا العنصر.

https://html.spec.whatwg.org/multipage/rendering.html#being -rendered

يتم تقديم عنصر إذا كان لديه أية مربعات المرتبطة CSS تخطيط، وصناديق تخطيط SVG، أو بعض ما يعادلها في اللغات التصميم الأخرى.

إذا لم يقم jsdom بتنفيذ أجزاء التخطيط ، ألا يعني ذلك تطبيق "عدم العرض"؟

هذه الرسالة لأي شخص يصل إلى مؤشر ترابط جيثب هذا ويريد فقط طريقة لاجتياز اختباراته دون تغيير تطبيقات وظائفه.

copypasta لأعلى ملفات الاختبار الخاصة بك:

// Expose JSDOM Element constructor
global.Element = (new JSDOM()).window.Element;
// 'Implement' innerText in JSDOM: https://github.com/jsdom/jsdom/issues/1245
Object.defineProperty(global.Element.prototype, 'innerText', {
  get() {
    return this.textContent;
  },
});

بطبيعة الحال ، تنطبق التحذيرات من المناقشة أعلاه.

في حالة تعرض أي شخص آخر لهذه المشكلة ، فقد اتخذت خطوة واحدة إلى الأمام واستخدمت الحزمة sanitize-html للحصول على ما يفعله المتصفح بشكل أساسي (لاحظ أنني لم أستورد إعداد JSDOM لأنني وجدت أنه لم يكن ضروريًا عند وضع هذا في ملف إعداد Jest الخاص بي ولكن إذا كنت لا تستخدم Jest ، فأنت تريد استخدام الإعداد global.Element = (new JSDOM()).window.Element الذي أوصى bennypowers ):

Object.defineProperty(global.Element.prototype, 'innerText', {
  get() {
    return sanitizeHtml(this.textContent, {
      allowedTags: [], // remove all tags and return text content only
      allowedAttributes: {}, // remove all tags and return text content only
    });
  },
  configurable: true, // make it so that it doesn't blow chunks on re-running tests with things like --watch
});

كانت لدي حاجة مماثلة ولكني أردت الذهاب إلى أبعد قليلاً من مجرد استخدام textContent - مرة أخرى ، لن يكون هذا تمثيلًا دقيقًا لما تفعله المتصفحات بالفعل ، خاصة فيما يتعلق بالعناصر المخفية بواسطة css ، لكنه جيد يكفي لحالة الاستخدام الخاصة بي:

function innerText(el)
  el = el.cloneNode(true) // can skip if mutability isn't a concern
  el.querySelectorAll('script,style').forEach(s => s.remove())
  return el.textContent
}

يا للأسف!

يبدو أن المواصفات تقول:

إذا لم يتم تقديم هذا العنصر ، أو إذا كان وكيل المستخدم وكيل مستخدم لا يتبع CSS ، فقم [التركيز مضافًا] بإرجاع نفس القيمة مثل سمة textContent IDL على هذا العنصر.

أعتقد أن الحل سيكون بعد ذلك ببساطة لإرجاع textContent.

نحن نطبق ما يكفي من CSS التي لا أعتقد أن ذلك ينطبق. نحن فقط لا ننفذ أجزاء التخطيط ...

domenic يرجى النظر في تفسير أكثر ليبرالية للمواصفات

يُسمح صراحةً باستخدام textContent كعنصر احتياطي ، عندما يكون تطبيق قواعد CSS مكلفًا للغاية

أيضًا ، تم تحديد innerText على أنه getter و setter

بالنظر إلى أنني محرر المواصفات ، يمكنني أن أؤكد على وجه اليقين أنه "عندما يكون تطبيق قواعد CSS مكلفًا للغاية" ليس ما تقوله المواصفات.

.. كان هذا هو تفسيري لـ "إذا كان وكيل المستخدم وكيل مستخدم بخلاف CSS"

ما الفرق بين "وكيل مستخدم CSS" و "وكيل مستخدم بخلاف CSS"؟

ماذا عن:
يمكن لوكيل مستخدم CSS "تطبيق قواعد CSS" وإخراج النتيجة (رسومية أو نصية)
وكيل مستخدم غير CSS غبي جدًا "لتطبيق قواعد CSS"

نحن نطبق ما يكفي من CSS التي لا أعتقد أن ذلك ينطبق.

ماذا تعني؟ window.getComputedStyle؟

لا يزال الرجوع إلى textContent أفضل من عدم تنفيذ واجهة قياسية

ربما يمكننا فقط استخدام textContent لاستبدال نتيجة innerText أثناء إجراء الاختبارات بـ jsdom . فمثلا:

describe('mytest', () => {
  beforeAll(() => {
    Object.defineProperty(HTMLElement.prototype, 'innerText', {
      get() {
        return this.textContent;
      }
    });
  });
  it('should ok', () => {
  // test assertions
  });
});
هل كانت هذه الصفحة مفيدة؟
0 / 5 - 0 التقييمات