توسيع أدوات مطوري البرامج

تضيف إضافات "أدوات مطوّري البرامج" ميزات إلى "أدوات مطوّري البرامج في Chrome" من خلال الوصول إلى واجهات برمجة التطبيقات الخاصة بأدوات مطوّري البرامج عبر صفحة "أدوات مطوّري البرامج" التي تتم إضافتها إلى الإضافة.

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

تشمل واجهات برمجة التطبيقات الخاصة بأدوات مطوّري البرامج ما يلي:

صفحة "أدوات مطوّري البرامج"

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

  • إنشاء لوحات والتفاعل معها باستخدام واجهات برمجة التطبيقات devtools.panels، بما في ذلك إضافة صفحات إضافات أخرى كلوحات أو أشرطة جانبية إلى نافذة "أدوات مطوّري البرامج"
  • الحصول على معلومات عن النافذة التي تم فحصها وتقييم الرمز في النافذة التي تم فحصها باستخدام devtools.inspectedWindow واجهات برمجة التطبيقات
  • الحصول على معلومات عن طلبات الشبكة باستخدام واجهات برمجة التطبيقات devtools.network
  • توسيع لوحة المسجِّل باستخدام واجهات برمجة التطبيقات devtools.recorder
  • الحصول على معلومات عن حالة التسجيل في لوحة الأداء باستخدام واجهات برمجة التطبيقات devtools.performance

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

إنشاء إضافة "أدوات مطوّري البرامج"

لإنشاء صفحة "أدوات مطوّري البرامج" لإضافتك، أضِف الحقل devtools_page في بيان الإضافة:

{
  "name": ...
  "version": "1.0",
  "devtools_page": "devtools.html",
  ...
}

يجب أن يشير الحقل devtools_page إلى صفحة HTML. بما أنّ صفحة "أدوات مطوّري البرامج" يجب أن تكون محلية في إضافتك، ننصحك بتحديدها باستخدام عنوان URL نسبي.

لا تتوفّر أعضاء واجهة برمجة التطبيقات chrome.devtools إلا للصفحات التي يتم تحميلها داخل نافذة "أدوات مطوّري البرامج" أثناء فتح هذه النافذة. لا يمكن للنصوص البرمجية للمحتوى وصفحات الإضافات الأخرى الوصول إلى واجهات برمجة التطبيقات هذه.

مساحة الاسم `browser` وإضافات "أدوات مطوّري البرامج"

يتم إيقاف مساحة الاسم browser التي تم طرحها في Chrome 148 للإضافات التي تُعلن عن devtools_page. ينطبق إلغاء الاشتراك على الإضافة بأكملها، وليس على صفحة "أدوات مطوّري البرامج" فقط، بل على كل سياق نص برمجي يتم فيه تشغيل واجهات برمجة التطبيقات الخاصة بالإضافات. واصِل استخدام chrome.* في جميع هذه الإضافات.

السبب هو وجود فجوة في التوافق مع webextension-polyfill. إنّ واجهات برمجة التطبيقات chrome.devtools.* هي واجهات برمجة تطبيقات تستخدم معاودة الاتصال فقط، ولا تعرض حاليًا الوعود بشكل أصلي، لذا تعتمد إضافات "أدوات مطوّري البرامج" عادةً على polyfill لتغليفها. يتخطّى polyfill عملية التغليف كلما تم تحديد browser، على افتراض أنّ المضيف قد أنجز العمل من قبل. إذا فعّل Chrome browser لهذه الإضافات، لن ينفّذ polyfill أي عملية وستتوقف طلبات chrome.devtools.* عن عرض الوعود. يسمح إيقاف browser لـ polyfill بمواصلة عملية التغليف.

يؤدي إلغاء الاشتراك نفسه أيضًا إلى إيقاف التغييرات الأخرى التي تم إجراؤها على واجهة برمجة التطبيقات للمراسلة في Chrome 148 لهذه الإضافات، بما في ذلك ردود Promise في runtime.onMessage. سيتم رفع هذا القيد عندما تتيح واجهات برمجة التطبيقات الخاصة بأدوات مطوّري البرامج الوعود بشكل أصلي.

عناصر واجهة مستخدم "أدوات مطوّري البرامج": اللوحات وأجزاء الشريط الجانبي

بالإضافة إلى عناصر واجهة المستخدم العادية للإضافة، مثل إجراءات المتصفّح وقوائم السياق والنوافذ المنبثقة، يمكن لإضافة "أدوات مطوّري البرامج" إضافة عناصر واجهة مستخدم إلى نافذة "أدوات مطوّري البرامج":

  • اللوحة هي علامة تبويب على المستوى الأعلى، مثل لوحات "العناصر" و"المصادر" و"الشبكة".
  • جزء الشريط الجانبي يعرض واجهة مستخدم تكميلية ذات صلة بلوحة. إنّ أجزاء "الأنماط" و"الأنماط المحتسَبة" و"مستمعو الأحداث" في لوحة "العناصر" هي أمثلة على أجزاء الشريط الجانبي. استنادًا إلى إصدار Chrome الذي تستخدمه وموضع تثبيت نافذة "أدوات مطوّري البرامج"، قد تبدو أجزاء الشريط الجانبي كما في الصورة المثال التالية:
نافذة "أدوات مطوّري البرامج" تعرض لوحة "العناصر" ولوحة الشريط الجانبي "الأنماط".
نافذة "أدوات مطوّري البرامج" تعرض لوحة "العناصر" وجزء الشريط الجانبي "الأنماط".

كل لوحة هي ملف HTML خاص بها، ويمكن أن تتضمّن موارد أخرى (JavaScript وCSS والصور وما إلى ذلك). لإنشاء لوحة أساسية، استخدِم الرمز التالي:

chrome.devtools.panels.create("My Panel",
    "MyPanelIcon.png",
    "Panel.html",
    function(panel) {
      // code invoked on panel creation
    }
);

يمكن لرمز JavaScript الذي يتم تنفيذه في لوحة أو جزء شريط جانبي الوصول إلى واجهات برمجة التطبيقات نفسها التي يمكن لصفحة "أدوات مطوّري البرامج" الوصول إليها.

لإنشاء جزء شريط جانبي أساسي، استخدِم الرمز التالي:

chrome.devtools.panels.elements.createSidebarPane("My Sidebar",
    function(sidebar) {
        // sidebar initialization code here
        sidebar.setObject({ some_data: "Some data to show" });
});

هناك عدة طرق لعرض المحتوى في جزء شريط جانبي:

  • محتوى HTML: استخدِم setPage() لتحديد صفحة HTML لعرضها في الجزء.
  • بيانات JSON: مرِّر كائن JSON إلى setObject().
  • تعبير JavaScript: مرِّر تعبيرًا إلى setExpression(). تقيِّم "أدوات مطوّري البرامج" التعبير في سياق الصفحة التي تم فحصها، ثم تعرض القيمة المعروضة.

بالنسبة إلى setObject() وsetExpression()، يعرض الجزء القيمة كما تظهر في وحدة تحكّم "أدوات مطوّري البرامج". مع ذلك، تتيح لك setExpression() عرض عناصر DOM وكائنات JavaScript عشوائية، بينما لا تتيح setObject() سوى كائنات JSON.

التواصل بين مكوّنات الإضافة

تصف الأقسام التالية بعض الطرق المفيدة للسماح لمكوّنات إضافة "أدوات مطوّري البرامج" بالتواصل مع بعضها البعض.

إضافة نص برمجي للمحتوى

لإضافة نص برمجي للمحتوى، استخدِم scripting.executeScript():

// DevTools page -- devtools.js
chrome.scripting.executeScript({
  target: {
    tabId: chrome.devtools.inspectedWindow.tabId
  },
  files: ["content_script.js"]
});

يمكنك استرداد رقم تعريف علامة التبويب للنافذة التي تم فحصها باستخدام السمة inspectedWindow.tabId.

إذا سبق أن تم إدراج نص برمجي للمحتوى، يمكنك استخدام واجهات برمجة التطبيقات للمراسلة للتواصل معه.

تقييم JavaScript في النافذة التي تم فحصها

يمكنك استخدام طريقة inspectedWindow.eval() لتنفيذ رمز JavaScript في سياق الصفحة التي تم فحصها. يمكنك استدعاء طريقة eval() من صفحة "أدوات مطوّري البرامج" أو لوحة أو جزء شريط جانبي.

يتم تلقائيًا تقييم التعبير في سياق الإطار الرئيسي للصفحة. inspectedWindow.eval() تستخدِم سياق تنفيذ النص البرمجي والخيارات نفسها التي يتم إدخالها في وحدة تحكّم "أدوات مطوّري البرامج"، ما يتيح الوصول إلى ميزات واجهة برمجة التطبيقات لأدوات وحدة تحكّم "أدوات مطوّري البرامج" عند استخدام eval(). على سبيل المثال، استخدِمها لفحص أول عنصر نص برمجي ضمن قسم <head> في مستند HTML:

chrome.devtools.inspectedWindow.eval(
  "inspect($$('head script')[0])",
  function(result, isException) { }
);

يمكنك أيضًا ضبط useContentScriptContext على true عند استدعاء inspectedWindow.eval() لتقييم التعبير في السياق نفسه الذي تستخدمه النصوص البرمجية للمحتوى. لاستخدام هذا الخيار، استخدِم إعلانًا ثابتًا للنص البرمجي للمحتوى قبل استدعاء eval()، إما عن طريق استدعاء executeScript() أو عن طريق تحديد نص برمجي للمحتوى في ملف manifest.json. بعد تحميل سياق النص البرمجي للمحتوى، يمكنك أيضًا استخدام هذا الخيار لإضافة نصوص برمجية إضافية للمحتوى.

تمرير العنصر المحدّد إلى نص برمجي للمحتوى

لا يمكن للنص البرمجي للمحتوى الوصول مباشرةً إلى العنصر المحدّد حاليًا. مع ذلك، يمكن لأي رمز تنفّذه باستخدام inspectedWindow.eval() الوصول إلى وحدة تحكّم "أدوات مطوّري البرامج" وواجهات برمجة التطبيقات لأدوات وحدة التحكّم. على سبيل المثال، يمكنك استخدام $0 في الرمز الذي تم تقييمه للوصول إلى العنصر المحدّد.

لتمرير العنصر المحدّد إلى نص برمجي للمحتوى:

  1. أنشئ طريقة في النص البرمجي للمحتوى تأخذ العنصر المحدّد كمعلَمة.

    function setSelectedElement(el) {
        // do something with the selected element
    }
    
  2. استدعِ الطريقة من صفحة "أدوات مطوّري البرامج" باستخدام inspectedWindow.eval() مع الخيار useContentScriptContext: true.

    chrome.devtools.inspectedWindow.eval("setSelectedElement($0)",
        { useContentScriptContext: true });
    

يحدّد الخيار useContentScriptContext: true أنّه يجب تقييم التعبير في السياق نفسه الذي تستخدمه النصوص البرمجية للمحتوى، لذا يمكنه الوصول إلى طريقة setSelectedElement.

الحصول على مرجع window للوحة مرجعية

لاستدعاء postMessage() من لوحة "أدوات مطوّري البرامج"، ستحتاج إلى مرجع لكائن window الخاص بها. احصل على نافذة iframe للوحة من معالج الأحداث panel.onShown:

extensionPanel.onShown.addListener(function (extPanelWindow) {
    extPanelWindow instanceof Window; // true
    extPanelWindow.postMessage( // …
});

إرسال رسائل من النصوص البرمجية التي تم إدراجها إلى صفحة "أدوات مطوّري البرامج"

لا يمكن للرمز الذي تم إدراجه مباشرةً في الصفحة بدون نص برمجي للمحتوى، بما في ذلك عن طريق إلحاق علامة <script> أو استدعاء inspectedWindow.eval()، إرسال رسائل إلى صفحة "أدوات مطوّري البرامج" باستخدام runtime.sendMessage(). بدلاً من ذلك، ننصحك بدمج النص البرمجي الذي تم إدراجه مع نص برمجي للمحتوى يمكن أن يكون بمثابة وسيط، واستخدام طريقة window.postMessage(). يستخدِم المثال التالي النص البرمجي في الخلفية من القسم السابق:

// injected-script.js

window.postMessage({
  greeting: 'hello there!',
  source: 'my-devtools-extension'
}, '*');
// content-script.js

window.addEventListener('message', function(event) {
  // Only accept messages from the same frame
  if (event.source !== window) {
    return;
  }

  var message = event.data;

  // Only accept messages that we know are ours. Note that this is not foolproof
  // and the page can easily spoof messages if it wants to.
  if (typeof message !== 'object' || message === null ||
      message.source !== 'my-devtools-extension') {
    return;
  }

  chrome.runtime.sendMessage(message);
});

يمكنك العثور على تقنيات بديلة أخرى لتمرير الرسائل على GitHub.

رصد وقت فتح "أدوات مطوّري البرامج" وإغلاقها

لتتبُّع ما إذا كانت نافذة "أدوات مطوّري البرامج" مفتوحة، أضِف مستمعًا لـ onConnect إلى مشغّل الخدمة واستخدِم connect() من صفحة "أدوات مطوّري البرامج". بما أنّ كل علامة تبويب يمكن أن تكون لها نافذة "أدوات مطوّري البرامج" الخاصة بها مفتوحة، قد تتلقّى أحداث connect متعددة. لتتبُّع ما إذا كانت أي نافذة "أدوات مطوّري البرامج" مفتوحة، احسِب أحداث connect وdisconnect كما هو موضّح في المثال التالي:

// background.js
var openCount = 0;
chrome.runtime.onConnect.addListener(function (port) {
    if (port.name == "devtools-page") {
      if (openCount == 0) {
        alert("DevTools window opening.");
      }
      openCount++;

      port.onDisconnect.addListener(function(port) {
          openCount--;
          if (openCount == 0) {
            alert("Last DevTools window closing.");
          }
      });
    }
});

تنشئ صفحة "أدوات مطوّري البرامج" اتصالاً على النحو التالي:

// devtools.js

// Create a connection to the service worker
const serviceWorkerConnection = chrome.runtime.connect({
    name: "devtools-page"
});

// Send a periodic heartbeat to keep the port open.
setInterval(() => {
  port.postMessage("heartbeat");
}, 15000);

أمثلة على إضافات "أدوات مطوّري البرامج"

تأتي الأمثلة في هذه الصفحة من الصفحات التالية:

  • إضافة Polymer Devtools: تستخدِم العديد من الأدوات المساعدة التي يتم تشغيلها في صفحة المضيف للاستعلام عن حالة DOM/JS لإرسالها مرة أخرى إلى اللوحة المخصّصة.
  • إضافة React DevTools: تستخدِم وحدة فرعية من أداة العرض لإعادة استخدام مكوّنات واجهة مستخدم "أدوات مطوّري البرامج" .
  • Ember Inspector: إضافة أساسية مشترَكة مع أدوات تكييف لكل من Chrome وFirefox.
  • Coquette-inspect: إضافة نظيفة تستند إلى React مع وكيل تصحيح أخطاء تم إدراجه في صفحة المضيف.
  • الإضافات النموذجية تتضمّن المزيد من الإضافات المفيدة التي يمكنك تثبيتها وتجربتها والاستفادة منها.

مزيد من المعلومات

للحصول على معلومات عن واجهات برمجة التطبيقات العادية التي يمكن للإضافات استخدامها، اطّلِع على chrome.* واجهات برمجة التطبيقات وواجهات برمجة تطبيقات الويب.

لا تنسَ إرسال التعليقات! تساعدنا ملاحظاتك واقتراحاتك في تحسين واجهات برمجة التطبيقات.

أمثلة

يمكنك العثور على أمثلة تستخدِم واجهات برمجة التطبيقات الخاصة بأدوات مطوّري البرامج في النماذج.