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

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

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

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

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

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

  • אפשר ליצור חלוניות ולקיים איתן אינטראקציה באמצעות ממשקי ה-API של devtools.panels, כולל הוספה של דפים אחרים של תוספים כחלוניות או כסרגלי צד לחלון כלי הפיתוח.
  • אפשר לקבל מידע על החלון שנבדק ולהעריך קוד בחלון שנבדק באמצעות ממשקי devtools.inspectedWindow API.
  • אפשר לקבל מידע על בקשות לרשת באמצעות ממשקי ה-API של devtools.network.
  • אפשר להרחיב את החלונית Recorder באמצעות ממשקי ה-API‏ devtools.recorder.
  • אפשר לקבל מידע על סטטוס התיעוד של חלונית הביצועים באמצעות ממשקי ה-API של devtools.performance.

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

יצירת תוסף לכלי הפיתוח

כדי ליצור דף DevTools לתוסף, מוסיפים את השדה devtools_page למניפסט של התוסף:

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

השדה devtools_page חייב להפנות לדף HTML. מכיוון שדף כלי הפיתוח צריך להיות מקומי לתוסף, מומלץ לציין אותו באמצעות כתובת URL יחסית.

חברי ה-API‏ chrome.devtools זמינים רק לדפים שנטענו בחלון כלי הפיתוח בזמן שהחלון הזה פתוח. לסקריפטים של תוכן ולדפים אחרים של תוספים אין גישה לממשקי ה-API האלה.

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

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

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

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

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

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

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

כל חלונית היא קובץ 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 כדי לגשת לרכיב שנבחר.

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

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

    function setSelectedElement(el) {
        // do something with the selected element
    }
    
  2. מבצעים קריאה לשיטה מהדף של כלי הפיתוח באמצעות 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 – משתמש במודול משנה של ה-renderer כדי לעשות שימוש חוזר ברכיבי ממשק המשתמש של כלי הפיתוח.
  • Ember Inspector – תוסף ליבה משותף עם מתאמים ל-Chrome ול-Firefox.
  • Coquette-inspect – תוסף נקי שמבוסס על React עם סוכן ניפוי באגים שמוזרק לדף המארח.
  • בקטע תוספים לדוגמה יש עוד תוספים שכדאי להתקין, לנסות וללמוד מהם.

מידע נוסף

למידע על ממשקי ה-API הרגילים שתוספים יכולים להשתמש בהם, אפשר לעיין במאמר chrome.* ‫APIs ו-web APIs.

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

דוגמאות

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