סקירה כללית
תוסף לכלי הפיתוח מוסיף פונקציונליות לכלי הפיתוח ל-Chrome. התוסף יכול להוסיף חלוניות חדשות בממשק המשתמש וסרגלי צד, ליצור אינטראקציה עם הדף שנבדק, לקבל מידע על בקשות רשת ועוד. הצגת תוספים מומלצים לכלי הפיתוח לתוספי DevTools יש גישה לקבוצה נוספת של ממשקי API ספציפיים לתוספי DevTools:
תוסף לכלי הפיתוח בנוי כמו כל תוסף אחר: יכול להיות לו דף רקע, סקריפטים של תוכן ופריטים אחרים. בנוסף, לכל תוסף של כלי הפיתוח יש דף כלי פיתוח עם גישה לממשקי ה-API של כלי הפיתוח.

הדף 'כלי פיתוח'
מופע של דף כלי הפיתוח של התוסף נוצר בכל פעם שחלון כלי הפיתוח נפתח. הדף של כלי הפיתוח קיים למשך החיים של חלון כלי הפיתוח. לדף כלי הפיתוח יש גישה לממשקי DevTools API ולמערך מוגבל של ממשקי Extension API. באופן ספציפי, בדף כלי הפיתוח אפשר:
- אפשר ליצור אינטראקציה עם לוחות באמצעות ממשקי ה-API
devtools.panels. - אפשר לקבל מידע על החלון שנבדק ולהעריך קוד בחלון שנבדק באמצעות ממשקי
devtools.inspectedWindowAPI. - אפשר לקבל מידע על בקשות לרשת באמצעות ממשקי ה-API של
devtools.network.
דף כלי הפיתוח לא יכול להשתמש ברוב ממשקי ה-API של התוספים באופן ישיר. יש לו גישה לאותה קבוצת משנה של ממשקי extension ו-runtime API שאליה יש לסקריפט תוכן גישה. בדומה לסקריפט תוכן, דף בכלי הפיתוח יכול לתקשר עם דף הרקע באמצעות העברת הודעות. דוגמה מופיעה במאמר בנושא הוספת סקריפט תוכן.
יצירת תוסף לכלי הפיתוח
כדי ליצור דף DevTools לתוסף, מוסיפים את השדה devtools_page למניפסט של התוסף:
{
"name": ...
"version": "1.0",
"minimum_chrome_version": "10.0",
"devtools_page": "devtools.html",
...
}
מופע של devtools_page שצוין במניפסט של התוסף נוצר לכל חלון של כלי הפיתוח שנפתח. יכול להיות שהדף יוסיף דפים אחרים של תוספים כחלוניות וסרגלי צד לחלון כלי הפיתוח באמצעות API devtools.panels.
מודולי ה-API chrome.devtools.* זמינים רק לדפים שנטענו בחלון כלי הפיתוח. לסקריפטים של תוכן ולדפים אחרים של תוספים אין את ממשקי ה-API האלה. לכן, ממשקי ה-API זמינים רק במהלך חיי החלון של כלי הפיתוח.
יש גם כמה ממשקי API של כלי הפיתוח שעדיין ניסיוניים. מידע נוסף זמין ב-chrome.experimental.* APIs לרשימת ממשקי API ניסיוניים והנחיות לשימוש בהם.
רכיבי ממשק משתמש בכלי הפיתוח: חלוניות וחלוניות צדדיות
בנוסף לרכיבי ממשק המשתמש הרגילים של תוסף, כמו פעולות בדפדפן, תפריטי הקשר וחלונות קופצים, תוסף ל-DevTools יכול להוסיף רכיבי ממשק משתמש לחלון DevTools:
- חלונית היא כרטיסייה ברמה העליונה, כמו החלוניות Elements (רכיבים), Sources (מקורות) ו-Network (רשת).
- חלונית צדדית שבה מוצג ממשק משתמש משלים שקשור לחלונית. החלוניות Styles (סגנונות), Computed Styles (סגנונות מחושבים) ו-Event Listeners (מאזיני אירועים) בחלונית Elements (רכיבים) הן דוגמאות לחלוניות צדדיות. (שימו לב: יכול להיות שהמראה של חלוניות סרגל הצד לא יהיה זהה לזה שבתמונה, בהתאם לגרסת Chrome שבה אתם משתמשים ולמיקום שבו חלון כלי הפיתוח מעוגן).

כל חלונית היא קובץ HTML משלה, שיכול לכלול משאבים אחרים (JavaScript, CSS, תמונות וכו'). כך נראה יצירה של חלונית בסיסית:
chrome.devtools.panels.create("My Panel",
"MyPanelIcon.png",
"Panel.html",
function(panel) {
// code invoked on panel creation
}
);
ל-JavaScript שמופעל בחלונית או בחלונית צדדית יש גישה לאותם ממשקי 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. - ביטוי JavaScript. מעבירים ביטוי אל
setExpression. כלי הפיתוח מעריכים את הביטוי בהקשר של הדף שנבדק ומציגים את הערך המוחזר.
גם עבור setObject וגם עבור setExpression, בחלונית מוצג הערך כפי שהוא יופיע במסוף של כלי הפיתוח. עם זאת, setExpression מאפשרת להציג רכיבי DOM ואובייקטים שרירותיים של JavaScript, בעוד ש-setObject תומכת רק באובייקטים של JSON.
תקשורת בין רכיבי התוסף
בקטעים הבאים מתוארים כמה תרחישים אופייניים לתקשורת בין הרכיבים השונים של תוסף DevTools.
החדרה של סקריפט תוכן
בדף כלי הפיתוח אי אפשר להתקשר ישירות אל tabs.executeScript. כדי להחדיר סקריפט תוכן מדף כלי הפיתוח, צריך לאחזר את המזהה של הכרטיסייה של החלון שנבדק באמצעות המאפיין 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);
});
});
הערכת JavaScript בחלון שנבדק
אפשר להשתמש בשיטה inspectedWindow.eval כדי להריץ קוד JavaScript בהקשר של הדף שנבדק. אפשר להפעיל את השיטה eval מדף, מחלונית או מחלונית צדדית בכלי הפיתוח.
כברירת מחדל, הביטוי מוערך בהקשר של המסגרת הראשית של הדף. יכול להיות שאתם מכירים את התכונות של commandline API בכלי הפיתוח, כמו בדיקת רכיבים (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 אם אין לכם צורך לגשת להקשר של JavaScript בדף שנבדק. אזהרות מפורטות והשוואה בין שתי השיטות מופיעות במאמר inspectedWindow.
העברת הרכיב שנבחר לסקריפט תוכן
לסקריפט התוכן אין גישה ישירה לאלמנט שנבחר כרגע. עם זאת, לכל קוד שמריצים באמצעות inspectedWindow.eval יש גישה למסוף DevTools ולממשקי ה-API של שורת הפקודה.
לדוגמה, בקוד שעבר הערכה אפשר להשתמש ב-$0 כדי לגשת לרכיב שנבחר.
כדי להעביר את הרכיב שנבחר לסקריפט תוכן:
- יוצרים שיטה בסקריפט התוכן שמקבלת את הרכיב שנבחר כארגומנט.
- מבצעים קריאה לשיטה מהדף של כלי הפיתוח באמצעות
inspectedWindow.evalעם האפשרותuseContentScriptContext: true.
הקוד בסקריפט התוכן יכול להיראות כך:
function setSelectedElement(el) {
// do something with the selected element
}
מפעילים את השיטה מדף כלי הפיתוח כך:
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( // …
});
העברת הודעות מסקריפטים של תוכן לדף כלי הפיתוח
ההודעות בין דף כלי הפיתוח לבין סקריפטים של תוכן הן עקיפות, דרך דף הרקע.
כששולחים הודעה אל סקריפט תוכן, דף הרקע יכול להשתמש בשיטה tabs.sendMessage, שמפנה הודעה לסקריפטים של תוכן בכרטיסייה ספציפית, כמו שמוצג במאמר הוספת סקריפט תוכן.
כששולחים הודעה מסקריפט תוכן, אין שיטה מוכנה מראש לשליחת הודעה למופע הנכון של דף כלי הפיתוח שמשויך לכרטיסייה הנוכחית. כפתרון עקיף, אפשר להגדיר את דף כלי הפיתוח כך שיצור חיבור לטווח ארוך עם דף הרקע, ודף הרקע ישמור מיפוי של מזהי הכרטיסיות לחיבורים, כדי שיוכל לנתב כל הודעה לחיבור הנכון.
// 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;
});
דף כלי הפיתוח (או החלונית או חלונית הצד) יוצר את החיבור באופן הבא:
// Create a connection to the background page
var backgroundPageConnection = chrome.runtime.connect({
name: "panel"
});
backgroundPageConnection.postMessage({
name: 'init',
tabId: chrome.devtools.inspectedWindow.tabId
});
העברת הודעות מסקריפטים מוזרקים לדף כלי הפיתוח
הפתרון שלמעלה מתאים לסקריפטים של תוכן, אבל אם הקוד מוחדר ישירות לדף (למשל, באמצעות הוספה של תג <script> או באמצעות inspectedWindow.eval), צריך להשתמש בשיטה אחרת. בהקשר הזה, runtime.sendMessage לא יעביר הודעות לסקריפט ברקע כמצופה.
כפתרון עקיף, אפשר לשלב את הסקריפט המוזרק עם סקריפט תוכן שפועל כמתווך. כדי להעביר הודעות לסקריפט התוכן, אפשר להשתמש ב-API 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
if (typeof message !== 'object' || message === null ||
!message.source === 'my-devtools-extension') {
return;
}
chrome.runtime.sendMessage(message);
});
ההודעה תעבור עכשיו מהסקריפט המוזרק, לסקריפט התוכן, לסקריפט הרקע ולבסוף לדף כלי הפיתוח.
כאן אפשר לקרוא על שתי טכניקות חלופיות להעברת הודעות.
זיהוי מתי כלי הפיתוח נפתחים ונסגרים
אם התוסף צריך לעקוב אחרי הפתיחה של חלון כלי הפיתוח, אפשר להוסיף מאזין onConnect לדף הרקע ולקרוא ל-connect מדף כלי הפיתוח. יכול להיות שתקבלו כמה אירועי חיבור, כי לכל כרטיסייה יכול להיות חלון כלי פיתוח משלה. כדי לעקוב אחרי פתיחה של חלון 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.js
// Create a connection to the background page
var backgroundPageConnection = chrome.runtime.connect({
name: "devtools-page"
});
דוגמאות לתוספים לכלי הפיתוח
אפשר לעיין במקור של הדוגמאות הבאות לתוספים לכלי הפיתוח:
- Polymer Devtools Extension – משתמש בהרבה רכיבי עזר שפועלים בדף המארח כדי לשלוח שאילתות למצב DOM/JS ולשלוח אותן בחזרה לחלונית המותאמת אישית.
- React DevTools Extension – משתמש במודול משנה של Blink כדי לעשות שימוש חוזר ברכיבי ממשק משתמש של כלי הפיתוח.
- Ember Inspector – תוסף ליבה משותף עם מתאמים ל-Chrome ול-Firefox.
- Coquette-inspect – תוסף נקי שמבוסס על React עם סוכן ניפוי באגים שמוזרק לדף המארח.
- בגלריית התוספים של כלי הפיתוח ובתוספים לדוגמה יש עוד אפליקציות שכדאי להתקין, לנסות וללמוד מהן.
מידע נוסף
למידע על ממשקי ה-API הרגילים שתוספים יכולים להשתמש בהם, אפשר לעיין במאמר chrome.* APIs ו-web APIs.
נשמח לקבל מכם משוב! ההערות וההצעות שלכם עוזרות לנו לשפר את ממשקי ה-API.
דוגמאות
דוגמאות לשימוש בממשקי API של כלי הפיתוח מופיעות בקטע דוגמאות.