DevTools को बड़ा किया जा रहा है

खास जानकारी

DevTools एक्सटेंशन, Chrome DevTools में फ़ंक्शन जोड़ता है. यह नए यूज़र इंटरफ़ेस (यूआई) पैनल और साइडबार जोड़ सकता है, जांचे गए पेज के साथ इंटरैक्ट कर सकता है, नेटवर्क अनुरोधों के बारे में जानकारी पा सकता है, और भी बहुत कुछ कर सकता है. DevTools के चुनिंदा एक्सटेंशन देखें. DevTools एक्सटेंशन के पास, DevTools के लिए बने एक्सटेंशन एपीआई के एक और सेट का ऐक्सेस होता है:

DevTools एक्सटेंशन, किसी भी दूसरे एक्सटेंशन की तरह ही होता है: इसमें बैकग्राउंड पेज, कॉन्टेंट स्क्रिप्ट, और अन्य आइटम हो सकते हैं. इसके अलावा, हर DevTools एक्सटेंशन में एक DevTools पेज होता है, जिसमें DevTools API का ऐक्सेस होता है.

आर्किटेक्चर डायग्राम, जिसमें जांच की गई विंडो और बैकग्राउंड पेज के साथ बातचीत करने वाला DevTools पेज दिखाया गया है. बैकग्राउंड पेज को दिखाया गया है, जो कॉन्टेंट स्क्रिप्ट के साथ कम्यूनिकेट कर रहा है और एक्सटेंशन एपीआई को ऐक्सेस कर रहा है.
       DevTools पेज के पास DevTools API का ऐक्सेस होता है. उदाहरण के लिए, पैनल बनाना.

DevTools पेज

जब भी DevTools विंडो खुलती है, तब एक्सटेंशन के DevTools पेज का एक इंस्टेंस बन जाता है. DevTools पेज, DevTools विंडो के खुले रहने तक मौजूद रहता है. DevTools पेज पर, DevTools API और एक्सटेंशन एपीआई के सीमित सेट का ऐक्सेस होता है. खास तौर पर, DevTools पेज पर ये काम किए जा सकते हैं:

  • devtools.panels एपीआई का इस्तेमाल करके पैनल बनाएं और उनसे इंटरैक्ट करें.
  • devtools.inspectedWindow एपीआई का इस्तेमाल करके, जांच की गई विंडो के बारे में जानकारी पाएं और जांच की गई विंडो में कोड का आकलन करें.
  • devtools.network एपीआई का इस्तेमाल करके, नेटवर्क अनुरोधों के बारे में जानकारी पाएं.

DevTools पेज, ज़्यादातर एक्सटेंशन एपीआई का सीधे तौर पर इस्तेमाल नहीं कर सकता. इसमें 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 एपीआई का इस्तेमाल करके, DevTools विंडो में पैनल और साइडबार के तौर पर अन्य एक्सटेंशन पेज जोड़ सकता है.

chrome.devtools.* एपीआई मॉड्यूल, सिर्फ़ DevTools विंडो में लोड किए गए पेजों के लिए उपलब्ध होते हैं. कॉन्टेंट स्क्रिप्ट और अन्य एक्सटेंशन पेजों में ये एपीआई नहीं होते. इसलिए, एपीआई सिर्फ़ DevTools विंडो के खुले रहने तक उपलब्ध होते हैं.

DevTools के कुछ एपीआई अब भी एक्सपेरिमेंट के तौर पर उपलब्ध हैं. chrome.experimental.* देखें. एपीआई पर जाएं.

DevTools के यूज़र इंटरफ़ेस (यूआई) एलिमेंट: पैनल और साइडबार पैनल

ब्राउज़र ऐक्शन, कॉन्टेक्स्ट मेन्यू, और पॉप-अप जैसे सामान्य एक्सटेंशन यूज़र इंटरफ़ेस (यूआई) एलिमेंट के अलावा, DevTools एक्सटेंशन, DevTools विंडो में यूज़र इंटरफ़ेस (यूआई) एलिमेंट जोड़ सकता है:

  • पैनल एक टॉप-लेवल टैब होता है, जैसे कि एलिमेंट, सोर्स, और नेटवर्क पैनल.
  • साइडबार पैनल, किसी पैनल से जुड़ा अतिरिक्त यूज़र इंटरफ़ेस (यूआई) दिखाता है. एलिमेंट पैनल में मौजूद स्टाइल, कंप्यूटेड स्टाइल, और इवेंट लिसनर पैनल, साइडबार पैनल के उदाहरण हैं. (ध्यान दें कि साइडबार पैनल की इमेज, Chrome के इस्तेमाल किए जा रहे वर्शन और DevTools विंडो के डॉक किए जाने की जगह के हिसाब से अलग-अलग हो सकती है.)

DevTools विंडो में, एलिमेंट पैनल और स्टाइल साइडबार पैनल दिख रहा है.

हर पैनल एक अलग एचटीएमएल फ़ाइल होती है. इसमें अन्य रिसॉर्स (JavaScript, सीएसएस, इमेज वगैरह) शामिल किए जा सकते हैं. बुनियादी पैनल बनाने का तरीका कुछ ऐसा दिखता है:

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

किसी पैनल या साइडबार पैनल में चलाए गए JavaScript के पास, DevTools पेज के एपीआई का ऐक्सेस होता है.

एलिमेंट पैनल के लिए, साइडबार पैनल बनाने का तरीका कुछ ऐसा है:

chrome.devtools.panels.elements.createSidebarPane("My Sidebar",
    function(sidebar) {
        // sidebar initialization code here
        sidebar.setObject({ some_data: "Some data to show" });
});

साइडबार पैनल में कॉन्टेंट दिखाने के कई तरीके हैं:

  • एचटीएमएल कॉन्टेंट. पैनल में दिखाने के लिए कोई एचटीएमएल पेज तय करने के लिए, setPage को कॉल करें.
  • JSON डेटा. setObject को JSON ऑब्जेक्ट पास करें.
  • JavaScript एक्सप्रेशन. setExpression को कोई एक्सप्रेशन पास करें. DevTools, जांचे गए पेज के संदर्भ में एक्सप्रेशन का आकलन करता है और रिटर्न वैल्यू दिखाता है.

setObject और setExpression, दोनों के लिए पैनल में वैल्यू वैसी ही दिखती है जैसी कि DevTools कंसोल में दिखती है. हालांकि, setExpression की मदद से डीओएम एलिमेंट और मनमुताबिक JavaScript ऑब्जेक्ट दिखाए जा सकते हैं, जबकि 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);
    });
});

जांच की गई विंडो में JavaScript का आकलन करना

जांचे गए पेज के संदर्भ में JavaScript कोड को लागू करने के लिए, inspectedWindow.eval तरीके का इस्तेमाल किया जा सकता है. eval तरीके को DevTools पेज, पैनल या साइडबार पैनल से शुरू किया जा सकता है.

डिफ़ॉल्ट रूप से, एक्सप्रेशन का आकलन पेज के मुख्य फ़्रेम के संदर्भ में किया जाता है. अब, आपको DevTools के कमांडलाइन एपीआई की सुविधाओं के बारे में पता हो सकता है. जैसे, एलिमेंट की जांच करना (inspect(elem)), फ़ंक्शन पर ब्रेक करना (debug(fn)), क्लिपबोर्ड पर कॉपी करना (copy()) वगैरह. inspectedWindow.eval(), स्क्रिप्ट को चलाने के उसी कॉन्टेक्स्ट और विकल्पों का इस्तेमाल करता है जो DevTools कंसोल में टाइप किए गए कोड के लिए इस्तेमाल किए जाते हैं. इससे, eval फ़ंक्शन में इन एपीआई को ऐक्सेस करने की अनुमति मिलती है. उदाहरण के लिए, SOAK किसी एलिमेंट की जांच करने के लिए इसका इस्तेमाल करता है:

chrome.devtools.inspectedWindow.eval(
  "inspect($$('head script[data-soak=main]')[0])",
  function(result, isException) { }
);

इसके अलावा, कॉन्टेंट स्क्रिप्ट के उसी कॉन्टेक्स्ट में एक्सप्रेशन का आकलन करने के लिए, inspectedWindow.eval() के लिए useContentScriptContext: true विकल्प का इस्तेमाल करें. useContentScriptContext: true के साथ eval को कॉल करने से, कॉन्टेंट स्क्रिप्ट का कॉन्टेक्स्ट create. इसलिए, eval को कॉल करने से पहले, आपको कॉन्टेक्स्ट स्क्रिप्ट लोड करनी होगी. इसके लिए, executeScript को कॉल करें या manifest.json फ़ाइल में कॉन्टेंट स्क्रिप्ट तय करें.

संदर्भ स्क्रिप्ट का कॉन्टेक्स्ट मौजूद होने के बाद, इस विकल्प का इस्तेमाल करके ज़्यादा कॉन्टेंट स्क्रिप्ट डाली जा सकती हैं.

eval का तरीका सही संदर्भ में इस्तेमाल करने पर काफ़ी असरदार होता है. वहीं, गलत तरीके से इस्तेमाल करने पर यह खतरनाक हो सकता है. अगर आपको जांचे गए पेज के JavaScript कॉन्टेक्स्ट का ऐक्सेस नहीं चाहिए, तो tabs.executeScript तरीके का इस्तेमाल करें. दोनों तरीकों के बारे में ज़्यादा जानकारी और सावधानियों के लिए, inspectedWindow देखें.

चुने गए एलिमेंट को कॉन्टेंट स्क्रिप्ट में पास करना

कॉन्टेंट स्क्रिप्ट के पास, चुने गए मौजूदा एलिमेंट का सीधा ऐक्सेस नहीं होता. हालांकि, inspectedWindow.eval का इस्तेमाल करके चलाए गए किसी भी कोड के पास, DevTools कंसोल और कमांड-लाइन एपीआई का ऐक्सेस होता है. उदाहरण के लिए, चुने गए एलिमेंट को ऐक्सेस करने के लिए, एलिमेंट की वैल्यू का आकलन करने वाले कोड में $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 ऑब्जेक्ट का रेफ़रंस चाहिए होगा. panel.onShown इवेंट हैंडलर से पैनल की iframe विंडो पाएं:

onShown.addListener(function callback)
extensionPanel.onShown.addListener(function (extPanelWindow) {
    extPanelWindow instanceof Window; // true
    extPanelWindow.postMessage( // …
});

कॉन्टेंट स्क्रिप्ट से DevTools पेज पर मैसेज भेजना

DevTools पेज और कॉन्टेंट स्क्रिप्ट के बीच मैसेज भेजने के लिए, बैकग्राउंड पेज का इस्तेमाल किया जाता है.

किसी कॉन्टेंट स्क्रिप्ट को मैसेज भेजने के लिए, बैकग्राउंड पेज tabs.sendMessage तरीके का इस्तेमाल कर सकता है. यह तरीका, किसी खास टैब में मौजूद कॉन्टेंट स्क्रिप्ट को मैसेज भेजता है. इस बारे में ज़्यादा जानने के लिए, कॉन्टेंट स्क्रिप्ट इंजेक्ट करना लेख पढ़ें.

किसी कॉन्टेंट स्क्रिप्ट से मैसेज भेजते समय, मौजूदा टैब से जुड़े सही 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 एपीआई का इस्तेमाल किया जा सकता है. यहां एक उदाहरण दिया गया है. इसमें पिछले सेक्शन की बैकग्राउंड स्क्रिप्ट का इस्तेमाल किया गया है:

// 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 पेज से connect को कॉल किया जा सकता है. हर टैब में अपनी 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 एक्सटेंशन - DevTools के यूज़र इंटरफ़ेस (यूआई) कॉम्पोनेंट का फिर से इस्तेमाल करने के लिए, Blink के सब-मोड्यूल का इस्तेमाल करता है.
  • Ember Inspector - Chrome और Firefox, दोनों के लिए अडैप्टर के साथ शेयर किया गया एक्सटेंशन कोर.
  • Coquette-inspect - यह React पर आधारित एक क्लीन एक्सटेंशन है. इसमें होस्ट पेज में डीबगिंग एजेंट इंजेक्ट किया गया है.
  • हमारी DevTools एक्सटेंशन गैलरी और सैंपल एक्सटेंशन में, ज़्यादा काम के ऐप्लिकेशन हैं. इन्हें इंस्टॉल करके आज़माया जा सकता है और इनसे सीखा जा सकता है.

ज़्यादा जानकारी

एक्सटेंशन जिन स्टैंडर्ड एपीआई का इस्तेमाल कर सकते हैं उनके बारे में जानने के लिए, chrome.* देखें. एपीआई और वेब एपीआई.

हमें सुझाव, राय दें या शिकायत करें! आपकी टिप्पणियों और सुझावों से, हमें एपीआई को बेहतर बनाने में मदद मिलती है.

उदाहरण

सैंपल में, DevTools API का इस्तेमाल करने वाले उदाहरण देखे जा सकते हैं.