توسعه DevTools

افزونه‌های DevTools با دسترسی به APIهای افزونه‌های مخصوص DevTools از طریق یک صفحه DevTools که به افزونه اضافه شده است، ویژگی‌هایی را به Chrome DevTools اضافه می‌کنند.

نمودار معماری که صفحه DevTools را در حال ارتباط با پنجره inspected و سرویس ورکر نشان می‌دهد. سرویس ورکر در حال ارتباط با اسکریپت‌های محتوا و دسترسی به APIهای افزونه نشان داده شده است.  صفحه DevTools به APIهای DevTools دسترسی دارد، به عنوان مثال، ایجاد پنل‌ها.
معماری افزونه DevTools.

APIهای افزونه‌ی مخصوص DevTools شامل موارد زیر هستند:

صفحه DevTools

وقتی یک پنجره DevTools باز می‌شود، یک افزونه DevTools نمونه‌ای از صفحه DevTools خود را ایجاد می‌کند که تا زمانی که پنجره باز است، وجود دارد. این صفحه به APIهای DevTools و APIهای افزونه دسترسی دارد و می‌تواند موارد زیر را انجام دهد:

  • با استفاده از APIهای devtools.panels ، پنل‌ها را ایجاد و با آنها تعامل کنید، از جمله اضافه کردن صفحات افزونه دیگر به عنوان پنل یا نوارهای کناری به پنجره DevTools.
  • با استفاده از APIهای devtools.inspectedWindow ، اطلاعاتی در مورد پنجره‌ی بازرسی‌شده دریافت کنید و کد موجود در پنجره‌ی بازرسی‌شده را ارزیابی کنید.
  • با استفاده از APIهای devtools.network ، اطلاعات مربوط به درخواست‌های شبکه را دریافت کنید.
  • پنل ضبط‌کننده را با استفاده از APIهای devtools.recorder گسترش دهید.
  • با استفاده از APIهای devtools.performance اطلاعاتی در مورد وضعیت ضبط پنل Performance دریافت کنید.

صفحه DevTools می‌تواند مستقیماً به APIهای افزونه‌ها دسترسی داشته باشد. این شامل امکان برقراری ارتباط با سرویس ورکر با استفاده از ارسال پیام (message transmission) نیز می‌شود.

یک افزونه DevTools ایجاد کنید

برای ایجاد یک صفحه DevTools برای افزونه خود، فیلد devtools_page را در مانیفست افزونه اضافه کنید:

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

فیلد devtools_page باید به یک صفحه HTML اشاره کند. از آنجا که صفحه DevTools باید محلی برای افزونه شما باشد، توصیه می‌کنیم آن را با استفاده از یک URL نسبی مشخص کنید.

اعضای API مربوط به chrome.devtools فقط برای صفحاتی که در پنجره DevTools بارگذاری شده‌اند، در حالی که آن پنجره باز است، در دسترس هستند. اسکریپت‌های محتوا و سایر صفحات افزونه به این APIها دسترسی ندارند.

عناصر رابط کاربری DevTools: پنل‌ها و پنل‌های نوار کناری

علاوه بر عناصر رابط کاربری معمول افزونه‌ها، مانند اقدامات مرورگر، منوهای زمینه و پنجره‌های بازشو، یک افزونه DevTools می‌تواند عناصر رابط کاربری را به پنجره DevTools اضافه کند:

  • یک پنل، یک تب سطح بالا است، مانند پنل‌های عناصر، منابع و شبکه.
  • یک پنل نوار کناری، رابط کاربری تکمیلی مربوط به یک پنل را ارائه می‌دهد. پنل‌های Styles، Computed Styles و Event Listeners در پنل Elements نمونه‌هایی از پنل‌های نوار کناری هستند. بسته به نسخه کرومی که استفاده می‌کنید و محل قرارگیری پنجره DevTools، پنل‌های نوار کناری شما ممکن است مانند تصویر نمونه زیر باشند:
پنجره‌ی DevTools که پنل Elements و پنل کناری Styles را نشان می‌دهد.
پنجره‌ی DevTools که پنل Elements و پنل کناری Styles را نشان می‌دهد.

هر پنل، فایل HTML مخصوص به خود را دارد که می‌تواند شامل منابع دیگری (جاوااسکریپت، CSS، تصاویر و غیره) باشد. برای ایجاد یک پنل ساده، از کد زیر استفاده کنید:

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

جاوا اسکریپتی که در یک پنل یا نوار کناری اجرا می‌شود، به همان APIهایی دسترسی دارد که صفحه DevTools به آنها دسترسی دارد.

برای ایجاد یک پنل سایدبار ساده، از کد زیر استفاده کنید:

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

چندین روش برای نمایش محتوا در یک پنل سایدبار وجود دارد:

  • محتوای HTML: برای تعیین یک صفحه HTML که در پنل نمایش داده می‌شود، تابع setPage() را فراخوانی کنید.
  • داده‌های JSON: یک شیء JSON را به setObject() ارسال کنید.
  • عبارت جاوا اسکریپت: یک عبارت را به setExpression() ارسال کنید. DevTools عبارت را در متن صفحه مورد بررسی ارزیابی می‌کند، سپس مقدار بازگشتی را نمایش می‌دهد.

برای هر دو setObject() و setExpression() ، پنجره مقدار را همانطور که در کنسول DevTools ظاهر می‌شود، نمایش می‌دهد. با این حال، setExpression() به شما امکان نمایش عناصر DOM و اشیاء دلخواه جاوا اسکریپت را می‌دهد، در حالی که setObject() فقط از اشیاء JSON پشتیبانی می‌کند.

ارتباط بین اجزای افزونه

بخش‌های زیر برخی از روش‌های مفید برای برقراری ارتباط اجزای افزونه DevTools با یکدیگر را شرح می‌دهند.

تزریق اسکریپت محتوا

برای تزریق یک اسکریپت محتوا، از scripting.executeScript() استفاده کنید:

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

شما می‌توانید شناسه‌ی برگه‌ی پنجره‌ی بازرسی‌شده را با استفاده از ویژگی inspectedWindow.tabId بازیابی کنید.

اگر یک اسکریپت محتوا قبلاً تزریق شده است، می‌توانید از APIهای پیام‌رسانی برای ارتباط با آن استفاده کنید.

ارزیابی جاوا اسکریپت در پنجره بازرسی شده

شما می‌توانید از متد inspectedWindow.eval() برای اجرای کد جاوا اسکریپت در متن صفحه‌ی بازرسی‌شده استفاده کنید. می‌توانید متد eval() را از یک صفحه، پنل یا نوار کناری DevTools فراخوانی کنید.

به طور پیش‌فرض، عبارت در چارچوب اصلی صفحه ارزیابی می‌شود. inspectedWindow.eval() از همان زمینه اجرای اسکریپت و گزینه‌های کد وارد شده در کنسول DevTools استفاده می‌کند که امکان دسترسی به ویژگی‌های API مربوط به DevTools Console Utilities را هنگام استفاده از eval() فراهم می‌کند. به عنوان مثال، از آن برای بررسی اولین عنصر اسکریپت در بخش <head> سند HTML استفاده کنید:

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

همچنین می‌توانید هنگام فراخوانی inspectedWindow.eval() برای ارزیابی عبارت در همان زمینه اسکریپت‌های محتوا، مقدار useContentScriptContext را روی true تنظیم کنید. برای استفاده از این گزینه، قبل از فراخوانی eval() ، از یک اعلان اسکریپت محتوای استاتیک استفاده کنید، یا با فراخوانی executeScript() یا با مشخص کردن یک اسکریپت محتوا در فایل manifest.json . پس از بارگذاری زمینه اسکریپت محتوا، می‌توانید از این گزینه برای تزریق اسکریپت‌های محتوای اضافی نیز استفاده کنید.

عنصر انتخاب شده را به یک اسکریپت محتوا منتقل کنید

اسکریپت محتوا به عنصر انتخاب شده فعلی دسترسی مستقیم ندارد. با این حال، هر کدی که با استفاده از inspectedWindow.eval() اجرا کنید، به کنسول DevTools و APIهای Console Utilities دسترسی دارد. برای مثال، در کد ارزیابی شده می‌توانید $0 برای دسترسی به عنصر انتخاب شده استفاده کنید.

برای ارسال عنصر انتخاب شده به یک اسکریپت محتوا:

  1. یک متد در اسکریپت محتوا ایجاد کنید که عنصر انتخاب شده را به عنوان آرگومان دریافت کند.

    function setSelectedElement(el) {
        // do something with the selected element
    }
    
  2. این متد را از صفحه DevTools با استفاده از inspectedWindow.eval() و با گزینه useContentScriptContext: true فراخوانی کنید.

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

گزینه useContentScriptContext: true مشخص می‌کند که عبارت باید در همان چارچوب اسکریپت‌های محتوا ارزیابی شود، بنابراین می‌تواند به متد setSelectedElement دسترسی داشته باشد.

window یک پنل مرجع را دریافت کنید

برای فراخوانی postMessage() از یک پنل devtools، به یک ارجاع به شیء window آن نیاز دارید. پنجره iframe یک پنل را از کنترل‌کننده رویداد panel.onShown دریافت کنید:

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

ارسال پیام از اسکریپت‌های تزریق‌شده به صفحه DevTools

کدی که مستقیماً و بدون اسکریپت محتوا به صفحه تزریق می‌شود، از جمله با افزودن تگ <script> یا فراخوانی inspectedWindow.eval() ، نمی‌تواند با استفاده از runtime.sendMessage() پیام‌هایی را به صفحه DevTools ارسال کند. در عوض، توصیه می‌کنیم اسکریپت تزریق شده خود را با یک اسکریپت محتوا که می‌تواند به عنوان واسطه عمل کند و با استفاده از متد 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 یافت.

تشخیص زمان باز و بسته شدن DevTools

برای ردیابی باز بودن پنجره DevTools، یک شنونده onConnect به service worker اضافه کنید و connect() را از صفحه DevTools فراخوانی کنید. از آنجا که هر تب می‌تواند پنجره DevTools خود را باز داشته باشد، ممکن است چندین رویداد اتصال دریافت کنید. برای ردیابی باز بودن هر پنجره DevTools، رویدادهای اتصال و قطع اتصال را همانطور که در مثال زیر نشان داده شده است، بشمارید:

// 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 اتصالی مانند این ایجاد می‌کند:

// 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);

نمونه‌های افزونه DevTools

مثال‌های این صفحه از صفحات زیر گرفته شده‌اند:

  • افزونه‌ی Polymer Devtools - از بسیاری از helperهای در حال اجرا در صفحه‌ی میزبان برای پرس‌وجو از وضعیت DOM/JS و ارسال آن به پنل سفارشی استفاده می‌کند.
  • افزونه React DevTools - از یک زیرماژول رندرکننده برای استفاده مجدد از کامپوننت‌های رابط کاربری DevTools استفاده می‌کند.
  • Ember Inspector - هسته افزونه مشترک با آداپتورهایی برای کروم و فایرفاکس.
  • Coquette-inspect - یک افزونه‌ی مبتنی بر React تمیز با یک عامل اشکال‌زدایی که به صفحه‌ی میزبان تزریق شده است.
  • افزونه‌های نمونه، افزونه‌های ارزشمندتری برای نصب، امتحان کردن و یادگیری دارند.

اطلاعات بیشتر

برای اطلاعات در مورد APIهای استانداردی که افزونه‌ها می‌توانند از آنها استفاده کنند، به chrome.* APIها و APIهای وب مراجعه کنید.

به ما بازخورد بدهید! نظرات و پیشنهادات شما به ما در بهبود APIها کمک می‌کند.

مثال‌ها

می‌توانید مثال‌هایی را که از APIهای DevTools استفاده می‌کنند، در Samples پیدا کنید.