نمای کلی
یک برنامه افزودنی DevTools عملکردی را به Chrome DevTools اضافه می کند. میتواند پنلها و نوارهای فرعی جدید رابط کاربری اضافه کند، با صفحه بازرسی شده تعامل داشته باشد، اطلاعاتی درباره درخواستهای شبکه دریافت کند و موارد دیگر. برنامه های افزودنی DevTools را مشاهده کنید. برنامههای افزودنی DevTools به مجموعه دیگری از APIهای برنامهافزونه ویژه DevTools دسترسی دارند:
یک برنامه افزودنی DevTools مانند هر برنامه افزودنی دیگر ساختار یافته است: می تواند صفحه پس زمینه، اسکریپت های محتوا و موارد دیگر داشته باشد. علاوه بر این، هر افزونه DevTools دارای یک صفحه DevTools است که به API های DevTools دسترسی دارد.
صفحه DevTools
هر بار که پنجره DevTools باز می شود، نمونه ای از صفحه DevTools برنامه افزودنی ایجاد می شود. صفحه DevTools برای طول عمر پنجره DevTools وجود دارد. صفحه DevTools به API های DevTools و مجموعه محدودی از برنامه های افزودنی API دسترسی دارد. به طور خاص، صفحه DevTools می تواند:
- با استفاده از برنامه های کاربردی
devtools.panels
، پنل ها را ایجاد کرده و با آنها تعامل داشته باشید. - اطلاعات مربوط به پنجره بازرسی شده را دریافت کنید و کد را در پنجره بازرسی شده با استفاده از APIs
devtools.inspectedWindow
ارزیابی کنید. - با استفاده از API
devtools.network
اطلاعاتی در مورد درخواست های شبکه دریافت کنید.
صفحه DevTools نمیتواند مستقیماً از بیشتر APIهای افزونه استفاده کند. به همان زیرمجموعه ای از برنامه های extension
و runtime
دسترسی دارد که یک اسکریپت محتوا به آن دسترسی دارد. مانند یک اسکریپت محتوا، یک صفحه DevTools میتواند با استفاده از ارسال پیام با صفحه پسزمینه ارتباط برقرار کند. برای مثال، تزریق یک اسکریپت محتوا را ببینید.
ایجاد یک افزونه DevTools
برای ایجاد یک صفحه DevTools برای برنامه افزودنی خود، فیلد devtools_page
در مانیفست افزونه اضافه کنید:
{
"name": ...
"version": "1.0",
"minimum_chrome_version": "10.0",
"devtools_page": "devtools.html",
...
}
نمونه ای از devtools_page
مشخص شده در مانیفست برنامه افزودنی شما برای هر پنجره DevTools باز می شود. این صفحه ممکن است با استفاده از devtools.panels
API صفحات افزونه دیگری را به عنوان پانل ها و نوارهای جانبی به پنجره DevTools اضافه کند.
ماژولهای chrome.devtools.*
فقط برای صفحاتی که در پنجره DevTools بارگذاری شدهاند در دسترس هستند. اسکریپت های محتوا و سایر صفحات افزونه این API ها را ندارند. بنابراین، APIها فقط در طول عمر پنجره DevTools در دسترس هستند.
همچنین برخی از API های DevTools وجود دارند که هنوز آزمایشی هستند. برای فهرست APIهای آزمایشی و دستورالعملهای نحوه استفاده از آنها به chrome.experimental.* API مراجعه کنید.
عناصر DevTools UI: پانل ها و پنجره های نوار کناری
افزونه DevTools علاوه بر عناصر معمول رابط کاربری افزونه، مانند اقدامات مرورگر، منوهای زمینه و پنجرههای بازشو، میتواند عناصر UI را به پنجره DevTools اضافه کند:
- پانل یک برگه سطح بالا است، مانند پانل های عناصر، منابع و شبکه.
- یک صفحه نوار کناری رابط کاربری تکمیلی مربوط به یک پانل را نشان می دهد. پنجرههای Styles، Computed Styles و Event Listeners در پانل Elements نمونههایی از پنجرههای نوار کناری هستند. (توجه داشته باشید که ظاهر پنجرههای نوار کناری ممکن است با تصویر مطابقت نداشته باشد، بسته به نسخه کروم که استفاده میکنید و جایی که پنجره DevTools در آن قرار دارد.)
هر پنل فایل HTML مخصوص به خود است که می تواند شامل منابع دیگری (جاوا اسکریپت، CSS، تصاویر و غیره) باشد. ایجاد یک پنل پایه به شکل زیر است:
chrome.devtools.panels.create("My Panel",
"MyPanelIcon.png",
"Panel.html",
function(panel) {
// code invoked on panel creation
}
);
جاوا اسکریپت اجرا شده در یک پانل یا نوار کناری به همان APIهایی که صفحه DevTools هستند دسترسی دارد.
ایجاد یک پانل پایه کناری برای پنل Elements به شکل زیر است:
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
ارسال کنید. - عبارت جاوا اسکریپت یک عبارت را به
setExpression
ارسال کنید. DevTools عبارت را در متن صفحه بازرسی شده ارزیابی می کند و مقدار بازگشتی را نمایش می دهد.
هم برای setObject
و هم setExpression
، صفحه مقدار را همانطور که در کنسول DevTools ظاهر می شود نمایش می دهد. با این حال، setExpression
به شما امکان می دهد عناصر DOM و اشیاء دلخواه جاوا اسکریپت را نمایش دهید، در حالی که setObject
فقط از اشیاء JSON پشتیبانی می کند.
برقراری ارتباط بین اجزای افزونه
بخشهای زیر برخی از سناریوهای معمولی برای برقراری ارتباط بین اجزای مختلف یک برنامه افزودنی DevTools را توضیح میدهند.
تزریق اسکریپت محتوا
صفحه DevTools نمیتواند مستقیماً tabs.executeScript
فراخوانی کند. برای تزریق یک اسکریپت محتوا از صفحه DevTools، باید شناسه برگه پنجره بازرسی شده را با استفاده از ویژگی inspectedWindow.tabId
بازیابی کنید و به صفحه پس زمینه پیام ارسال کنید. از صفحه پس زمینه، tabs.executeScript
برای تزریق اسکریپت فراخوانی کنید.
قطعه کد زیر نحوه تزریق یک اسکریپت محتوا با استفاده از executeScript
را نشان می دهد.
// DevTools page -- devtools.js
// Create a connection to the background page
var backgroundPageConnection = chrome.runtime.connect({
name: "devtools-page"
});
backgroundPageConnection.onMessage.addListener(function (message) {
// Handle responses from the background page, if any
});
// Relay the tab ID to the background page
chrome.runtime.sendMessage({
tabId: chrome.devtools.inspectedWindow.tabId,
scriptToInject: "content_script.js"
});
کد برای صفحه پس زمینه:
// Background page -- background.js
chrome.runtime.onConnect.addListener(function(devToolsConnection) {
// assign the listener function to a variable so we can remove it later
var devToolsListener = function(message, sender, sendResponse) {
// Inject a content script into the identified tab
chrome.tabs.executeScript(message.tabId,
{ file: message.scriptToInject });
}
// add the listener
devToolsConnection.onMessage.addListener(devToolsListener);
devToolsConnection.onDisconnect.addListener(function() {
devToolsConnection.onMessage.removeListener(devToolsListener);
});
});
ارزیابی جاوا اسکریپت در پنجره بازرسی شده
می توانید از روش inspectedWindow.eval
برای اجرای کد جاوا اسکریپت در متن صفحه بازرسی شده استفاده کنید. میتوانید روش eval
از یک صفحه DevTools، پانل یا نوار کناری فراخوانی کنید.
به طور پیش فرض، عبارت در زمینه چارچوب اصلی صفحه ارزیابی می شود. اکنون، ممکن است با ویژگیهای API خط فرمان DevTools مانند بازرسی عنصر ( inspect(elem)
)، شکستن توابع ( debug(fn)
)، کپی کردن در کلیپ بورد ( copy()
) و موارد دیگر آشنا باشید. inspectedWindow.eval()
از همان زمینه اجرای اسکریپت و گزینه هایی مانند کد تایپ شده در کنسول DevTools استفاده می کند که امکان دسترسی به این API ها را در eval فراهم می کند. به عنوان مثال، SOAK از آن برای بازرسی یک عنصر استفاده می کند:
chrome.devtools.inspectedWindow.eval(
"inspect($$('head script[data-soak=main]')[0])",
function(result, isException) { }
);
از طرف دیگر، از گزینه useContentScriptContext: true
برای inspectedWindow.eval()
استفاده کنید تا عبارت را در زمینه مشابه اسکریپت های محتوا ارزیابی کنید. فراخوانی eval
با useContentScriptContext: true
یک متن اسکریپت محتوا ایجاد نمی کند، بنابراین باید قبل از فراخوانی eval
یک متن اسکریپت بارگیری کنید، چه با فراخوانی executeScript
یا با تعیین یک اسکریپت محتوا در فایل manifest.json
.
هنگامی که زمینه متن اسکریپت وجود دارد، می توانید از این گزینه برای تزریق اسکریپت های محتوای اضافی استفاده کنید.
روش eval
زمانی قدرتمند است که در زمینه مناسب استفاده شود و در صورت استفاده نامناسب خطرناک است. اگر نیازی به دسترسی به زمینه جاوا اسکریپت صفحه بازرسی شده ندارید، از روش tabs.executeScript
استفاده کنید. برای احتیاطات دقیق و مقایسه این دو روش، به inspectedWindow
مراجعه کنید.
انتقال عنصر انتخاب شده به اسکریپت محتوا
اسکریپت محتوا دسترسی مستقیم به عنصر انتخابی فعلی ندارد. با این حال، هر کدی که با استفاده از inspectedWindow.eval
اجرا می کنید، به کنسول DevTools و APIهای خط فرمان دسترسی دارد. به عنوان مثال، در کد ارزیابی شده می توانید از $0
برای دسترسی به عنصر انتخاب شده استفاده کنید.
برای ارسال عنصر انتخاب شده به اسکریپت محتوا:
- یک متد در اسکریپت محتوا ایجاد کنید که عنصر انتخاب شده را به عنوان آرگومان دریافت کند.
- متد را از صفحه DevTools با استفاده از
inspectedWindow.eval
با گزینهuseContentScriptContext: true
فراخوانی کنید.
کد موجود در اسکریپت محتوای شما ممکن است چیزی شبیه به این باشد:
function setSelectedElement(el) {
// do something with the selected element
}
متد را از صفحه DevTools به این صورت فراخوانی کنید:
chrome.devtools.inspectedWindow.eval("setSelectedElement($0)",
{ useContentScriptContext: true });
گزینه useContentScriptContext: true
مشخص می کند که عبارت باید در چارچوبی مشابه با اسکریپت های محتوا ارزیابی شود، بنابراین می تواند به متد setSelectedElement
دسترسی داشته باشد.
دریافت window
پنل مرجع
برای postMessage
از پانل ابزارهای توسعه، به شی window
آن نیاز دارید. پنجره iframe یک پانل را از کنترل کننده رویداد panel.onShown
دریافت کنید:
onShown.addListener(function callback)
extensionPanel.onShown.addListener(function (extPanelWindow) {
extPanelWindow instanceof Window; // true
extPanelWindow.postMessage( // …
});
ارسال پیام از اسکریپت های محتوا به صفحه DevTools
پیام رسانی بین صفحه DevTools و اسکریپت های محتوا غیرمستقیم از طریق صفحه پس زمینه است.
هنگام ارسال پیام به یک اسکریپت محتوا، صفحه پسزمینه میتواند از روش tabs.sendMessage
استفاده کند، که پیامی را به اسکریپتهای محتوا در یک برگه خاص هدایت میکند، همانطور که در Injecting a Content Script نشان داده شده است.
هنگام ارسال پیام از یک اسکریپت محتوا، هیچ روش آماده ای برای ارسال پیام به نمونه صحیح صفحه DevTools مرتبط با برگه فعلی وجود ندارد. به عنوان راهحل، میتوانید از صفحه DevTools بخواهید یک ارتباط طولانی مدت با صفحه پسزمینه برقرار کند، و صفحه پسزمینه نقشه شناسههای برگهها را برای اتصالات نگه دارد تا بتواند هر پیام را به اتصال صحیح هدایت کند.
// background.js
var connections = {};
chrome.runtime.onConnect.addListener(function (port) {
var extensionListener = function (message, sender, sendResponse) {
// The original connection event doesn't include the tab ID of the
// DevTools page, so we need to send it explicitly.
if (message.name == "init") {
connections[message.tabId] = port;
return;
}
// other message handling
}
// Listen to messages sent from the DevTools page
port.onMessage.addListener(extensionListener);
port.onDisconnect.addListener(function(port) {
port.onMessage.removeListener(extensionListener);
var tabs = Object.keys(connections);
for (var i=0, len=tabs.length; i < len; i++) {
if (connections[tabs[i]] == port) {
delete connections[tabs[i]]
break;
}
}
});
});
// Receive message from content script and relay to the devTools page for the
// current tab
chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) {
// Messages from content scripts should have sender.tab set
if (sender.tab) {
var tabId = sender.tab.id;
if (tabId in connections) {
connections[tabId].postMessage(request);
} else {
console.log("Tab not found in connection list.");
}
} else {
console.log("sender.tab not defined.");
}
return true;
});
صفحه DevTools (یا پانل یا پانل نوار کناری) اتصال را به این صورت برقرار می کند:
// Create a connection to the background page
var backgroundPageConnection = chrome.runtime.connect({
name: "panel"
});
backgroundPageConnection.postMessage({
name: 'init',
tabId: chrome.devtools.inspectedWindow.tabId
});
ارسال پیام از اسکریپت های تزریق شده به صفحه DevTools
در حالی که راه حل فوق برای اسکریپت های محتوا کار می کند، کدی که مستقیماً به صفحه تزریق می شود (مثلاً از طریق اضافه کردن یک تگ <script>
یا از طریق inspectedWindow.eval
) به استراتژی متفاوتی نیاز دارد. در این زمینه، runtime.sendMessage
همانطور که انتظار می رود پیام ها را به اسکریپت پس زمینه ارسال نمی کند.
به عنوان یک راه حل، می توانید اسکریپت تزریق شده خود را با یک اسکریپت محتوا که به عنوان یک واسطه عمل می کند ترکیب کنید. برای ارسال پیام به اسکریپت محتوا، می توانید از window.postMessage
API استفاده کنید. در اینجا یک مثال با فرض اسکریپت پس زمینه از بخش قبل آورده شده است:
// 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
if (typeof message !== 'object' || message === null ||
!message.source === 'my-devtools-extension') {
return;
}
chrome.runtime.sendMessage(message);
});
پیام شما اکنون از اسکریپت تزریق شده، به اسکریپت محتوا، به اسکریپت پس زمینه و در نهایت به صفحه DevTools منتقل می شود.
همچنین می توانید دو تکنیک جایگزین ارسال پیام را در اینجا در نظر بگیرید.
تشخیص زمان باز و بسته شدن DevTools
اگر برنامه افزودنی شما باید باز بودن پنجره DevTools را ردیابی کند، میتوانید یک شنونده onConnect را به صفحه پسزمینه اضافه کنید و از صفحه 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 background page
var backgroundPageConnection = chrome.runtime.connect({
name: "devtools-page"
});
نمونه های برنامه افزودنی DevTools
منبع این نمونه های افزونه DevTools را مرور کنید:
- افزونه Polymer Devtools - از بسیاری از کمککنندگان در حال اجرا در صفحه میزبان برای پرسوجو از وضعیت DOM/JS استفاده میکند تا به پنل سفارشی ارسال شود.
- React DevTools Extension - از زیر ماژول Blink برای استفاده مجدد از اجزای DevTools UI استفاده می کند.
- Ember Inspector - هسته برنامه افزودنی مشترک با آداپتورهای کروم و فایرفاکس.
- Coquette-inspect - یک برنامه افزودنی تمیز مبتنی بر React با یک عامل اشکال زدایی که به صفحه میزبان تزریق شده است.
- گالری برنامه افزودنی DevTools و برنامههای افزودنی نمونه برنامههای ارزشمندتری برای نصب، امتحان کردن و یادگیری از آنها دارند.
اطلاعات بیشتر
برای اطلاعات در مورد APIهای استانداردی که برنامههای افزودنی میتوانند استفاده کنند، به chrome مراجعه کنید.* APIها و Web API .
به ما بازخورد بدهید! نظرات و پیشنهادات شما به ما در بهبود API ها کمک می کند.
نمونه ها
میتوانید نمونههایی را پیدا کنید که از APIهای DevTools در Samples استفاده میکنند.