Geliştirici Araçları'nın Kapsamını Genişletme

Genel Bakış

Geliştirici Araçları uzantısı, Chrome Geliştirici Araçları'na işlevsellik ekler. Yeni kullanıcı arayüzü panelleri ve kenar çubukları ekleyebilir, incelenen sayfayla etkileşimde bulunabilir, ağ istekleri hakkında bilgi alabilir ve daha fazlasını yapabilir. Öne çıkan Geliştirici Araçları uzantılarını görüntüleyin. Geliştirme Araçları uzantıları, Geliştirme Araçları'na özel ek bir uzantı API'leri grubuna erişebilir:

DevTools uzantıları diğer uzantılar gibi yapılandırılır: Arka plan sayfası, içerik komut dosyaları ve başka öğeler içerebilir. Ayrıca her Geliştirici Araçları uzantısının, Geliştirici Araçları API'lerine erişimi olan bir Geliştirici Araçları sayfası vardır.

Geliştirici Araçları sayfasının, incelenen pencere ve arka plan sayfasıyla iletişim kurduğunu gösteren mimari diyagram. Arka plan sayfası, içerik komut dosyalarıyla iletişim kurarak ve uzantı API'lerine erişerek gösterilir.
       Geliştirici Araçları sayfası, Geliştirici Araçları API'lerine (ör. panel oluşturma) erişebilir.

Geliştirici Araçları sayfası

Bir Geliştirici Araçları penceresi her açıldığında uzantının Geliştirici Araçları sayfasının bir örneği oluşturulur. Geliştirici Araçları sayfası, Geliştirici Araçları penceresi açık kaldığı sürece var olur. Geliştirme Araçları sayfasının Geliştirme Araçları API'lerine ve sınırlı bir uzantı API'leri grubuna erişimi vardır. Geliştirici Araçları sayfası özellikle şunları yapabilir:

  • devtools.panels API'lerini kullanarak panel oluşturma ve panellerle etkileşim kurma
  • İncelenen pencere hakkında bilgi alın ve devtools.inspectedWindow API'leri kullanarak incelenen penceredeki kodu değerlendirin.
  • devtools.network API'lerini kullanarak ağ istekleri hakkında bilgi edinin.

Geliştirici Araçları sayfası, uzantı API'lerinin çoğunu doğrudan kullanamaz. İçerik komut dosyalarının erişebildiği extension ve runtime API'lerinin aynı alt kümesine erişebilir. İçerik komut dosyası gibi, bir Geliştirici Araçları sayfası da Message Passing (Mesaj Geçirme) kullanarak arka plan sayfasıyla iletişim kurabilir. Örnek için İçerik Komut Dosyası Ekleme başlıklı makaleyi inceleyin.

Geliştirici Araçları uzantısı oluşturma

Uzantınız için bir DevTools sayfası oluşturmak üzere uzantı manifestine devtools_page alanını ekleyin:

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

Uzantınızın manifest dosyasında belirtilen devtools_page öğesinin bir örneği, açılan her bir DevTools penceresi için oluşturulur. Sayfa, devtools.panels API'sini kullanarak diğer uzantı sayfalarını paneller ve kenar çubukları olarak Geliştirme Araçları penceresine ekleyebilir.

chrome.devtools.* API modülleri yalnızca Geliştirici Araçları penceresinde yüklenen sayfalarda kullanılabilir. İçerik komut dosyaları ve diğer uzantı sayfalarında bu API'ler bulunmaz. Bu nedenle, API'ler yalnızca Geliştirici Araçları penceresinin kullanım süresi boyunca kullanılabilir.

Ayrıca, hâlâ deneysel aşamada olan bazı DevTools API'leri de vardır. chrome.experimental.* Deneysel API'lerin listesi ve bunların nasıl kullanılacağıyla ilgili yönergeler için API'ler sayfasına bakın.

Geliştirici Araçları kullanıcı arayüzü öğeleri: paneller ve kenar çubuğu bölmeleri

Tarayıcı işlemleri, bağlam menüleri ve pop-up'lar gibi normal uzantı kullanıcı arayüzü öğelerine ek olarak, bir DevTools uzantısı DevTools penceresine kullanıcı arayüzü öğeleri ekleyebilir:

  • Panel, Elements, Sources ve Network panelleri gibi üst düzey bir sekmedir.
  • Kenar çubuğu bölmesi, bir panelle ilgili ek kullanıcı arayüzü sunar. Öğeler panelindeki Stiller, Hesaplanan Stiller ve Etkinlik Dinleyicileri panoları, kenar çubuğu panolarına örnek olarak verilebilir. (Kullandığınız Chrome sürümüne ve Geliştirici Araçları penceresinin nereye yerleştirildiğine bağlı olarak, kenar çubuğu bölmelerinin görünümünün resimle eşleşmeyebileceğini unutmayın.)

Nesneler paneli ve Stiller kenar çubuğu bölmesini gösteren Geliştirici Araçları penceresi.

Her panel kendi HTML dosyasıdır ve diğer kaynakları (JavaScript, CSS, resimler vb.) içerebilir. Temel bir panel oluşturma işlemi şu şekilde görünür:

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

Bir panelde veya kenar çubuğu bölmesinde yürütülen JavaScript, Geliştirici Araçları sayfasıyla aynı API'lere erişebilir.

Öğeler paneli için temel bir kenar çubuğu bölmesi oluşturma işlemi şu şekilde görünür:

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

İçeriği kenar çubuğu bölmesinde göstermenin çeşitli yolları vardır:

  • HTML içeriği. Bölmede görüntülenecek bir HTML sayfası belirtmek için setPage işlevini çağırın.
  • JSON verileri. setObject işlevine bir JSON nesnesi iletin.
  • JavaScript ifadesi. setExpression'a ifade iletme DevTools, ifadeyi incelenen sayfanın bağlamında değerlendirir ve dönüş değerini gösterir.

Her ikisi için de (setObject ve setExpression) bölmede değer, DevTools konsolunda görüneceği şekilde gösterilir. Ancak setExpression, DOM öğelerini ve rastgele JavaScript nesnelerini görüntülemenize olanak tanırken setObject yalnızca JSON nesnelerini destekler.

Uzantı bileşenleri arasında iletişim kurma

Aşağıdaki bölümlerde, bir DevTools uzantısının farklı bileşenleri arasındaki iletişime ilişkin bazı tipik senaryolar açıklanmaktadır.

İçerik komut dosyası yerleştirme

Geliştirici Araçları sayfası tabs.executeScript doğrudan arayamaz. Geliştirici Araçları sayfasından bir içerik komut dosyası eklemek için inspectedWindow.tabId özelliğini kullanarak incelenen pencerenin sekmesinin kimliğini almanız ve arka plan sayfasına bir mesaj göndermeniz gerekir. Arka plan sayfasından, komut dosyasını yerleştirmek için tabs.executeScript işlevini çağırın.

Aşağıdaki kod snippet'lerinde, executeScript kullanarak içerik komut dosyası yerleştirme işlemi gösterilmektedir.

// 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"
});

Arka plan sayfasının kodu:

// 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);
    });
});

İncelenen pencerede JavaScript'i değerlendirme

İncelenen sayfa bağlamında JavaScript kodu yürütmek için inspectedWindow.eval yöntemini kullanabilirsiniz. eval yöntemini bir Geliştirici Araçları sayfasından, panelinden veya kenar çubuğu bölmesinden çağırabilirsiniz.

Varsayılan olarak ifade, sayfanın ana çerçevesi bağlamında değerlendirilir. Geliştirici Araçları'nın komut satırı API özelliklerini (ör. öğe inceleme (inspect(elem)), işlevlerde kesme (debug(fn)), panoya kopyalama (copy())) kullanıyor olabilirsiniz. inspectedWindow.eval(), Geliştirici Araçları konsoluna yazılan kodla aynı komut dosyası yürütme bağlamını ve seçeneklerini kullanır. Bu sayede, eval içinde bu API'lere erişilebilir. Örneğin, SOAK, bir öğeyi incelemek için bu özelliği kullanır:

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

Alternatif olarak, inspectedWindow.eval() için useContentScriptContext: true seçeneğini kullanarak ifadeyi içerik komut dosyalarıyla aynı bağlamda değerlendirin. eval işlevini useContentScriptContext: true ile çağırmak içerik komut dosyası bağlamı oluşturmaz. Bu nedenle, eval işlevini çağırmadan önce executeScript işlevini çağırarak veya manifest.json dosyasında bir içerik komut dosyası belirterek bir bağlam komut dosyası yüklemeniz gerekir.

Bağlam komut dosyası bağlamı oluşturulduktan sonra, ek içerik komut dosyaları yerleştirmek için bu seçeneği kullanabilirsiniz.

eval yöntemi, doğru bağlamda kullanıldığında güçlü, uygunsuz kullanıldığında ise tehlikelidir. İncelenen sayfanın JavaScript bağlamına erişmeniz gerekmiyorsa tabs.executeScript yöntemini kullanın. Ayrıntılı uyarılar ve iki yöntemin karşılaştırması için inspectedWindow başlıklı makaleyi inceleyin.

Seçili öğeyi bir içerik komut dosyasına aktarma

İçerik komut dosyası, şu anda seçili öğeye doğrudan erişemiyor. Ancak inspectedWindow.eval kullanarak yürüttüğünüz tüm kodlar, Geliştirici Araçları konsoluna ve komut satırı API'lerine erişebilir. Örneğin, değerlendirilen kodda seçili öğeye erişmek için $0 kullanabilirsiniz.

Seçili öğeyi bir içerik komut dosyasına iletmek için:

  • İçerik komut dosyasında, seçilen öğeyi bağımsız değişken olarak alan bir yöntem oluşturun.
  • useContentScriptContext: true seçeneğiyle inspectedWindow.eval kullanarak yöntemi Geliştirici Araçları sayfasından çağırın.

İçerik komut dosyanızdaki kod şu şekilde görünebilir:

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

Yöntemi Geliştirici Araçları sayfasından şu şekilde çağırın:

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

useContentScriptContext: true seçeneği, ifadenin içerik komut dosyalarıyla aynı bağlamda değerlendirilmesi gerektiğini belirtir. Bu nedenle, useContentScriptContext: true yöntemine erişebilir.setSelectedElement

Referans panelinin window değerini alma

Bir geliştirici araçları panelinden postMessage için window nesnesine referans vermeniz gerekir. panel.onShown etkinlik işleyicisinden bir panelin iFrame penceresini alın:

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

İçerik komut dosyalarından Geliştirici Araçları sayfasına mesaj gönderme

Geliştirici Araçları sayfası ile içerik komut dosyaları arasındaki mesajlaşma, arka plan sayfası aracılığıyla dolaylı olarak yapılır.

Bir içerik komut dosyasına mesaj gönderirken arka plan sayfası, İçerik Komut Dosyası Ekleme bölümünde gösterildiği gibi, belirli bir sekmedeki içerik komut dosyalarına mesaj yönlendiren tabs.sendMessage yöntemini kullanabilir.

Bir içerik komut dosyasından mesaj gönderirken, mesajı geçerli sekmeyle ilişkili doğru Geliştirici Araçları sayfası örneğine iletmek için hazır bir yöntem yoktur. Geçici çözüm olarak, Geliştirici Araçları sayfasının arka plan sayfasıyla uzun süreli bir bağlantı kurmasını sağlayabilir ve arka plan sayfasının, sekme kimliklerinin bağlantılarla eşlendiği bir harita tutmasını sağlayabilirsiniz. Böylece her mesajı doğru bağlantıya yönlendirebilir.

// 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;
});

Geliştirici Araçları sayfası (veya panel ya da kenar çubuğu bölmesi) bağlantıyı şu şekilde kurar:

// Create a connection to the background page
var backgroundPageConnection = chrome.runtime.connect({
    name: "panel"
});

backgroundPageConnection.postMessage({
    name: 'init',
    tabId: chrome.devtools.inspectedWindow.tabId
});

Enjekte edilen komut dosyalarından Geliştirici Araçları sayfasına mesaj gönderme

Yukarıdaki çözüm içerik komut dosyaları için işe yarasa da doğrudan sayfaya yerleştirilen kodlar (ör. <script> etiketi eklenerek veya inspectedWindow.eval aracılığıyla) farklı bir strateji gerektirir. Bu durumda, runtime.sendMessage, mesajları arka plan komut dosyasına beklendiği gibi iletmez.

Geçici çözüm olarak, yerleştirilen komut dosyanızı aracı görevi gören bir içerik komut dosyasıyla birleştirebilirsiniz. İçerik komut dosyasına mesaj iletmek için window.postMessage API'sini kullanabilirsiniz. Önceki bölümdeki arka plan komut dosyasının kullanıldığını varsayarak bir örnek aşağıda verilmiştir:

// 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);
});

Mesajınız artık yerleştirilen komut dosyasından içerik komut dosyasına, arka plan komut dosyasına ve son olarak da Geliştirici Araçları sayfasına aktarılacak.

Ayrıca, burada iki alternatif mesaj iletme tekniğini de inceleyebilirsiniz.

Geliştirici Araçları'nın açılıp kapandığını algılama

Uzantınızın Geliştirici Araçları penceresinin açık olup olmadığını izlemesi gerekiyorsa arka plan sayfasına bir onConnect dinleyicisi ekleyebilir ve Geliştirici Araçları sayfasından connect işlevini çağırabilirsiniz. Her sekmede kendi Geliştirici Araçları penceresi açık olabileceğinden birden fazla bağlantı etkinliği alabilirsiniz. Herhangi bir DevTools penceresinin açık olup olmadığını izlemek için aşağıdaki gibi bağlantı ve bağlantı kesme etkinliklerini saymanız gerekir:

// 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.");
          }
      });
    }
});

Geliştirici Araçları sayfası şu şekilde bir bağlantı oluşturur:

// devtools.js

// Create a connection to the background page
var backgroundPageConnection = chrome.runtime.connect({
    name: "devtools-page"
});

Geliştirici Araçları uzantısı örnekleri

Bu Geliştirici Araçları uzantısı örneklerinin kaynağına göz atın:

Daha fazla bilgi

Uzantıların kullanabileceği standart API'ler hakkında bilgi edinmek için chrome.* başlıklı makaleyi inceleyin. API'ler ve web API'leri.

Geri bildirimlerinizi bizimle paylaşın Yorumlarınız ve önerileriniz, API'leri geliştirmemize yardımcı olur.

Örnekler

Geliştirici Araçları API'lerini kullanan örnekleri Örnekler bölümünde bulabilirsiniz.