תוספים לכלי הפיתוח מוסיפים תכונות לכלי הפיתוח ל-Chrome באמצעות גישה לממשקי API של תוספים ספציפיים לכלי הפיתוח דרך דף כלי הפיתוח שנוסף לתוסף.
ממשקי ה-API של התוספים שספציפיים לכלי הפיתוח כוללים את האפשרויות הבאות:
הדף 'כלי פיתוח'
כשחלון של כלי הפיתוח נפתח, תוסף של כלי הפיתוח יוצר מופע של דף כלי הפיתוח שלו, שקיים כל עוד החלון פתוח. בדף הזה יש גישה לממשקי ה-API של כלי הפיתוח ולממשקי ה-API של התוספים, ואפשר לבצע בו את הפעולות הבאות:
- אפשר ליצור חלוניות ולקיים איתן אינטראקציה באמצעות ממשקי ה-API של
devtools.panels, כולל הוספה של דפים אחרים של תוספים כחלוניות או כסרגלי צד לחלון כלי הפיתוח. - אפשר לקבל מידע על החלון שנבדק ולהעריך קוד בחלון שנבדק באמצעות ממשקי ה-API של
devtools.inspectedWindow. - אפשר לקבל מידע על בקשות לרשת באמצעות ממשקי ה-API של
devtools.network. - אפשר להרחיב את החלונית של מכשיר ההקלטה באמצעות ממשקי ה-API
devtools.recorder. - אפשר לקבל מידע על סטטוס התיעוד של חלונית הביצועים באמצעות ממשקי ה-API של
devtools.performance.
דף כלי הפיתוח יכול לגשת ישירות לממשקי API של תוספים. ההרשאות כוללות את האפשרות ליצור קשר עם ה-service worker באמצעות העברת הודעות.
יצירת תוסף לכלי פיתוח
כדי ליצור דף DevTools לתוסף, מוסיפים את השדה devtools_page למניפסט של התוסף:
{
"name": ...
"version": "1.0",
"devtools_page": "devtools.html",
...
}
השדה devtools_page חייב להפנות לדף HTML. מכיוון שדף DevTools צריך להיות מקומי לתוסף, מומלץ לציין אותו באמצעות כתובת URL יחסית.
החברים ב-API chrome.devtools זמינים רק לדפים שנטענו בחלון כלי הפיתוח בזמן שהחלון הזה פתוח. לסקריפטים של תוכן ולדפים אחרים של תוספים אין גישה לממשקי ה-API האלה.
מרחב השמות של הדפדפן ותוספים לכלי פיתוח
בגרסאות Chrome 152 ואילך, תוספים עם דף כלי פיתוח יכולים להשתמש במרחב השמות browser.
בגרסאות Chrome ישנות יותר מ-152, מרחב השמות browser
הושבת לתוספים שמוצהר בהם
devtools_page. הביטול חל על התוסף כולו – לא רק על דף כלי הפיתוח, אלא על כל הקשר סקריפט שבו מופעלים ממשקי API של התוסף.
הסיבה הייתה פער בתאימות ל-webextension-polyfill.
ממשקי ה-API chrome.devtools.* בגרסאות ישנות יותר מ-Chrome 152 היו מבוססים על קריאות חוזרות בלבד – הם לא החזירו Promises באופן מקורי – ולכן תוספים לכלי הפיתוח הסתמכו בדרך כלל על ה-polyfill כדי לעטוף אותם. ה-polyfill מדלג על העטיפה בכל פעם שמוגדר browser, מתוך הנחה שהמארח כבר ביצע את העבודה. אם Chrome הפעיל את browser עבור התוספים האלה, ה-polyfill לא יבצע פעולה וקריאות ל-chrome.devtools.* יפסיקו להחזיר Promises. השארת browser במצב מושבת גרמה לכך שה-polyfill המשיך להתעטף.
הביטול הזה השבית גם את השינויים האחרים ב-Messaging API ב-Chrome 148 עבור התוספים האלה, כולל תגובות Promise ב-runtime.onMessage.
ההגבלה הוסרה אחרי שממשקי ה-API של כלי הפיתוח תמכו ב-Promises באופן מקורי.
רכיבים בממשק המשתמש של כלי הפיתוח: חלוניות וחלונות צדדיים
בנוסף לרכיבי ממשק המשתמש הרגילים של תוספים, כמו פעולות בדפדפן, תפריטי הקשר וחלונות קופצים, תוסף 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.
כדי ליצור חלונית בסיסית בסרגל הצד, משתמשים בקוד הבא:
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.
אם סקריפט תוכן כבר הוזרק, אפשר להשתמש בממשקי API להעברת הודעות כדי לתקשר איתו.
הערכת JavaScript בחלון שנבדק
אפשר להשתמש בשיטה inspectedWindow.eval() כדי להריץ קוד JavaScript בהקשר של הדף שנבדק. אפשר להפעיל את השיטה eval() מדף, מחלונית או מחלונית צדדית בכלי הפיתוח.
כברירת מחדל, הביטוי מוערך בהקשר של המסגרת הראשית של הדף.
inspectedWindow.eval() משתמש באותו הקשר ואותן אפשרויות של הפעלת סקריפט כמו קוד שהוזן במסוף כלי הפיתוח, מה שמאפשר גישה לתכונות של Console Utilities API בכלי הפיתוח כשמשתמשים ב-eval(). לדוגמה, אפשר להשתמש בו כדי לבדוק את רכיב הסקריפט הראשון בקטע <head> של מסמך ה-HTML:
chrome.devtools.inspectedWindow.eval(
"inspect($$('head script')[0])",
function(result, isException) { }
);
אפשר גם להגדיר את useContentScriptContext ל-true כשקוראים ל-inspectedWindow.eval() כדי להעריך את הביטוי באותו הקשר כמו סקריפטים של תוכן. כדי להשתמש באפשרות הזו, צריך להשתמש בהצהרה על סקריפט תוכן סטטי לפני ששולחים קריאה ל-eval(), או על ידי קריאה ל-executeScript() או על ידי ציון סקריפט תוכן בקובץ manifest.json. אחרי שההקשר של סקריפט התוכן נטען, אפשר להשתמש באפשרות הזו גם כדי להחדיר סקריפטים נוספים של תוכן.
העברת הרכיב שנבחר לסקריפט תוכן
לסקריפט התוכן אין גישה ישירה לרכיב שנבחר כרגע. עם זאת, לכל קוד שמריצים באמצעות inspectedWindow.eval() יש גישה למסוף DevTools ולממשקי ה-API של כלי המסוף. לדוגמה, בקוד שנבדק אפשר להשתמש ב-$0 כדי לגשת לרכיב שנבחר.
כדי להעביר את הרכיב שנבחר לסקריפט תוכן:
יוצרים שיטה בסקריפט התוכן שמקבלת את הרכיב שנבחר כארגומנט.
function setSelectedElement(el) { // do something with the selected element }מבצעים קריאה לשיטה מהדף של כלי הפיתוח באמצעות
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 ל-service worker וקוראים ל-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 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 Extension – משתמש בהרבה רכיבי עזר שפועלים בדף המארח כדי לבצע שאילתה על מצב DOM/JS, ואז שולח את התוצאה בחזרה לחלונית המותאמת אישית.
- React DevTools Extension – משתמש במודול משנה של כלי הרינדור כדי לעשות שימוש חוזר ברכיבי ממשק המשתמש של כלי הפיתוח.
- Ember Inspector – ליבת תוסף משותפת עם מתאמים ל-Chrome ול-Firefox.
- Coquette-inspect – תוסף נקי מבוסס-React עם סוכן ניפוי באגים שמוזרק לדף המארח.
- בקטע תוספים לדוגמה יש עוד תוספים שכדאי להתקין, לנסות וללמוד מהם.
מידע נוסף
למידע על ממשקי ה-API הרגילים שתוספים יכולים להשתמש בהם, אפשר לעיין במאמר chrome.* APIs ו-web APIs.
נשמח לקבל ממך משוב! ההערות וההצעות שלכם עוזרות לנו לשפר את ממשקי ה-API.
דוגמאות
דוגמאות לשימוש בממשקי API של כלי הפיתוח זמינות בקטע דוגמאות.