הרחבת כלי הפיתוח

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

דיאגרמת ארכיטקטורה שמראה את דף כלי פיתוח מתקשר עם החלון שנבדק ועם קובץ שירות (service worker). ה-service worker מוצג כשהוא מתקשר עם סקריפטים של תוכן וניגש ל-APIs של תוספים.
         לדף כלי הפיתוח יש גישה לממשקי DevTools API, למשל, ליצירת חלוניות.
ארכיטקטורת התוסף של כלי הפיתוח.

ממשקי ה-API של התוספים הספציפיים לכלי הפיתוח כוללים את האפשרויות הבאות:

הדף של כלי הפיתוח

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

  • אפשר ליצור חלוניות ולקיים איתן אינטראקציה באמצעות ממשקי ה-API של devtools.panels, כולל הוספה של דפים אחרים של תוספים כחלוניות או כסרגלי צד לחלון כלי הפיתוח.
  • אפשר לקבל מידע על החלון שנבדק ולהעריך קוד בחלון שנבדק באמצעות ממשקי devtools.inspectedWindow API.
  • אפשר לקבל מידע על בקשות לרשת באמצעות ממשקי ה-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‏ browser.devtools זמינים רק לדפים שנטענו בחלון כלי הפיתוח בזמן שהחלון הזה פתוח. לסקריפטים של תוכן ולדפים אחרים של התוסף אין גישה לממשקי ה-API האלה.

מרחב השמות של הדפדפן ותוספים לכלי פיתוח

בגרסאות Chrome 152 ואילך, תוספים עם דף כלי פיתוח יכולים להשתמש במרחב השמות browser.

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

הסיבה הייתה פער בתאימות ל-webextension-polyfill. ממשקי ה-API‏ browser.devtools.* בגרסאות קודמות ל-Chrome 152 היו מבוססי-callback בלבד – הם לא החזירו Promises באופן מובנה – ולכן תוספים לכלי הפיתוח הסתמכו בדרך כלל על ה-polyfill כדי לעטוף אותם. ה-polyfill מדלג על העטיפה בכל פעם שהמשתנה browser מוגדר, מתוך הנחה שהמארח כבר ביצע את הפעולה. אם Chrome הפעיל את browser עבור התוספים האלה, ה-polyfill לא יבצע פעולה וקריאות ל-browser.devtools.* יפסיקו להחזיר Promises. השארת browser במצב מושבת גרמה לכך שה-polyfill המשיך להתבצע.

ההסרה מהרשימה השביתה גם את השינויים האחרים ב-API של העברת ההודעות ב-Chrome 148 עבור התוספים האלה, כולל תגובות Promise ב-runtime.onMessage. ההגבלה הוסרה ברגע שממשקי ה-API של כלי הפיתוח תמכו ב-Promises באופן מקורי.

רכיבים בממשק המשתמש של כלי הפיתוח: חלוניות ולוחות צדדיים

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

  • חלונית היא כרטיסייה ברמה העליונה, כמו החלוניות Elements,‏ Sources ו-Network.
  • חלונית בסרגל הצד מציגה ממשק משתמש משלים שקשור לחלונית. החלוניות Styles (סגנונות), Computed Styles (סגנונות מחושבים) ו-Event Listeners (מאזיני אירועים) בחלונית Elements (רכיבים) הן דוגמאות לחלוניות בסרגל הצד. בהתאם לגרסת Chrome שבה אתם משתמשים ולמיקום שבו חלון כלי הפיתוח מעוגן, יכול להיות שהחלוניות בסרגל הצד ייראו כמו בדוגמה הבאה:
חלון כלי הפיתוח שבו מוצגת החלונית Elements (רכיבים) וסרגל הצד Styles (סגנונות).
חלון כלי הפיתוח שבו מוצגת החלונית Elements וסרגל הצד Styles.

כל חלונית היא קובץ HTML משלה, שיכול לכלול משאבים אחרים (JavaScript,‏ CSS, תמונות וכו'). כדי ליצור חלונית בסיסית, משתמשים בקוד הבא:

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

ל-JavaScript שמופעל בחלונית או בחלונית צדדית יש גישה לאותם ממשקי API כמו לדף DevTools.

כדי ליצור חלונית בסיסית בסרגל הצד, משתמשים בקוד הבא:

browser.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 לתקשר זה עם זה.

החדרת סקריפט תוכן

כדי להוסיף סקריפט תוכן, משתמשים ב-scripting.executeScript():

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

אפשר לאחזר את מזהה הכרטיסייה של החלון שנבדק באמצעות המאפיין inspectedWindow.tabId.

אם סקריפט תוכן כבר הוזרק, אפשר להשתמש בממשקי API להעברת הודעות כדי לתקשר איתו.

הערכת JavaScript בחלון שנבדק

אפשר להשתמש בשיטה inspectedWindow.eval() כדי להריץ קוד JavaScript בהקשר של הדף שנבדק. אפשר להפעיל את השיטה eval() מדף, מחלונית או מחלונית צדדית בכלי הפיתוח.

כברירת מחדל, הביטוי מוערך בהקשר של המסגרת הראשית של הדף. inspectedWindow.eval() משתמש באותו הקשר ואותן אפשרויות של הרצת סקריפט כמו קוד שהוזן במסוף כלי הפיתוח, מה שמאפשר גישה לתכונות של Console Utilities API בכלי הפיתוח כשמשתמשים ב-eval(). לדוגמה, אפשר להשתמש בו כדי לבדוק את רכיב הסקריפט הראשון בקטע <head> של מסמך ה-HTML:

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

אפשר גם להגדיר את useContentScriptContext ל-true כשקוראים ל-inspectedWindow.eval() כדי להעריך את הביטוי באותו הקשר כמו סקריפטים של תוכן. כדי להשתמש באפשרות הזו, צריך להשתמש בהצהרה על סקריפט תוכן סטטי לפני ששולחים קריאה ל-eval(), או על ידי קריאה ל-executeScript() או על ידי ציון סקריפט תוכן בקובץ manifest.json. אחרי שההקשר של סקריפט התוכן נטען, אפשר גם להשתמש באפשרות הזו כדי להחדיר סקריפטים נוספים של תוכן.

העברת הרכיב שנבחר לסקריפט תוכן

לסקריפט התוכן אין גישה ישירה לרכיב שנבחר כרגע. עם זאת, לכל קוד שמריצים באמצעות inspectedWindow.eval() יש גישה למסוף DevTools ולממשקי ה-API של כלי המסוף. לדוגמה, בקוד מוערך אפשר להשתמש ב-$0 כדי לגשת לרכיב שנבחר.

כדי להעביר את הרכיב שנבחר לסקריפט תוכן:

  1. יוצרים שיטה בסקריפט התוכן שמקבלת את הרכיב שנבחר כארגומנט.

    function setSelectedElement(el) {
        // do something with the selected element
    }
    
  2. מבצעים קריאה לשיטה מדף כלי הפיתוח באמצעות inspectedWindow.eval() עם האפשרות useContentScriptContext: true.

    browser.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;
  }

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

טכניקות חלופיות אחרות להעברת הודעות מפורטות ב-GitHub.

זיהוי מתי כלי הפיתוח נפתחים ונסגרים

כדי לעקוב אחרי הפתיחה של חלון כלי הפיתוח, מוסיפים מאזין onConnect ל-service worker וקוראים ל-connect() מדף כלי הפיתוח. יכול להיות שתקבלו כמה אירועי חיבור כי לכל כרטיסייה יכול להיות חלון משלו של כלי הפיתוח. כדי לעקוב אחרי פתיחה של חלון DevTools, סופרים את אירועי החיבור והניתוק כמו בדוגמה הבאה:

// background.js
var openCount = 0;
browser.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 = browser.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 – משתמש במודול משנה של רכיב הרינדור כדי לעשות שימוש חוזר ברכיבי ממשק המשתמש של כלי הפיתוח.
  • Ember Inspector – ליבת תוסף משותפת עם מתאמים ל-Chrome ול-Firefox.
  • Coquette-inspect – תוסף נקי מבוסס React עם סוכן ניפוי באגים שמוזרק לדף המארח.
  • בקטע תוספים לדוגמה יש עוד תוספים שכדאי להתקין, לנסות וללמוד מהם.

מידע נוסף

מידע על ממשקי API סטנדרטיים שתוספים יכולים להשתמש בהם זמין במאמר browser.*‎ ‫APIs ו-web APIs.

נשמח לקבל ממך משוב. ההערות וההצעות שלכם עוזרות לנו לשפר את ממשקי ה-API.

דוגמאות

דוגמאות לשימוש בממשקי API של כלי הפיתוח מופיעות בקטע דוגמאות.