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

खास जानकारी

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

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

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

DevTools पेज

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

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

कुछ DevTools एपीआई अब भी एक्सपेरिमेंटल स्टेज में हैं. chrome.experimental.* देखें एक्सपेरिमेंटल एपीआई की सूची और उन्हें इस्तेमाल करने के दिशा-निर्देशों के लिए, एपीआई देखें.

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

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

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

DevTools विंडो में, Elements पैनल और Styles साइडबार पैन दिखाया गया है.

हर पैनल, अपनी एचटीएमएल फ़ाइल होती है. इसमें अन्य रिसॉर्स (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 की मदद से, DOM एलिमेंट और आर्बिट्ररी 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 को कॉल करने से, कॉन्टेंट स्क्रिप्ट कॉन्टेक्स्ट नहीं बनता. इसलिए, eval को कॉल करने से पहले, executeScript को कॉल करके या manifest.json फ़ाइल में कोई कॉन्टेंट स्क्रिप्ट तय करके, कॉन्टेक्स्ट स्क्रिप्ट लोड करनी होगी.

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

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

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

कॉन्टेंट स्क्रिप्ट के पास, फ़िलहाल चुने गए एलिमेंट का सीधे तौर पर ऐक्सेस नहीं होता. हालांकि, एक्ज़ीक्यूट किए गए किसी भी कोड के पास, DevTools कंसोल और कमांड-लाइन एपीआई का ऐक्सेस होता है.inspectedWindow.eval उदाहरण के लिए, जांच किए गए कोड में, चुने गए एलिमेंट को ऐक्सेस करने के लिए, $0 का इस्तेमाल किया जा सकता है.

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

  • कॉन्टेंट स्क्रिप्ट में एक ऐसा तरीका बनाएं जो चुने गए एलिमेंट को आर्ग्युमेंट के तौर पर लेता हो.
  • useContentScriptContext: true विकल्प के साथ, inspectedWindow.eval का इस्तेमाल करके, DevTools पेज से इस तरीके को कॉल करें.

आपकी कॉन्टेंट स्क्रिप्ट में मौजूद कोड कुछ ऐसा दिख सकता है:

function setSelectedElement(el) {
    // do something with the selected element
}

DevTools पेज से इस तरीके को ऐसे शुरू करें:

chrome.devtools.inspectedWindow.eval("setSelectedElement($0)",
    { useContentScriptContext: true });

useContentScriptContext: true विकल्प से पता चलता है कि एक्सप्रेशन की जांच, कॉन्टेंट स्क्रिप्ट के जैसे ही कॉन्टेक्स्ट में की जानी चाहिए. इसलिए, यह setSelectedElement तरीके को ऐक्सेस कर सकता है.

रेफ़रंस पैनल का window पाना

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

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

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

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

उदाहरण

आपको सैंपल में, DevTools एपीआई का इस्तेमाल करने वाले उदाहरण मिल सकते हैं.