layout/tools/layout-debug/ui/content/layoutdebug.js

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/layout/tools/layout-debug/ui/content/layoutdebug.js	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,434 @@
     1.4 +/* This Source Code Form is subject to the terms of the Mozilla Public
     1.5 + * License, v. 2.0. If a copy of the MPL was not distributed with this
     1.6 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     1.7 +
     1.8 +var gBrowser;
     1.9 +var gProgressListener;
    1.10 +var gDebugger;
    1.11 +var gRTestIndexList;
    1.12 +var gRTestURLList = null;
    1.13 +
    1.14 +const nsILayoutDebuggingTools = Components.interfaces.nsILayoutDebuggingTools;
    1.15 +const nsIDocShell = Components.interfaces.nsIDocShell;
    1.16 +const nsIWebProgressListener = Components.interfaces.nsIWebProgressListener;
    1.17 +
    1.18 +const NS_LAYOUT_DEBUGGINGTOOLS_CONTRACTID = "@mozilla.org/layout-debug/layout-debuggingtools;1";
    1.19 +
    1.20 +
    1.21 +function nsLDBBrowserContentListener()
    1.22 +{
    1.23 +  this.init();
    1.24 +}
    1.25 +
    1.26 +nsLDBBrowserContentListener.prototype = {
    1.27 +
    1.28 +  init : function()
    1.29 +    {
    1.30 +      this.mStatusText = document.getElementById("status-text");
    1.31 +      this.mURLBar = document.getElementById("urlbar");
    1.32 +      this.mForwardButton = document.getElementById("forward-button");
    1.33 +      this.mBackButton = document.getElementById("back-button");
    1.34 +      this.mStopButton = document.getElementById("stop-button");
    1.35 +    },
    1.36 +
    1.37 +  QueryInterface : function(aIID)
    1.38 +    {
    1.39 +      if (aIID.equals(Components.interfaces.nsIWebProgressListener) ||
    1.40 +          aIID.equals(Components.interfaces.nsISupportsWeakReference) ||
    1.41 +          aIID.equals(Components.interfaces.nsISupports))
    1.42 +        return this;
    1.43 +      throw Components.results.NS_NOINTERFACE;
    1.44 +    },
    1.45 +
    1.46 +  // nsIWebProgressListener implementation
    1.47 +  onStateChange : function(aWebProgress, aRequest, aStateFlags, aStatus)
    1.48 +    {
    1.49 +      if (!(aStateFlags & nsIWebProgressListener.STATE_IS_NETWORK) ||
    1.50 +          aWebProgress != gBrowser.webProgress)
    1.51 +        return;
    1.52 +
    1.53 +      if (aStateFlags & nsIWebProgressListener.STATE_START) {
    1.54 +        this.setButtonEnabled(this.mStopButton, true);
    1.55 +        this.setButtonEnabled(this.mForwardButton, gBrowser.canGoForward);
    1.56 +        this.setButtonEnabled(this.mBackButton, gBrowser.canGoBack);
    1.57 +        this.mStatusText.value = "loading...";
    1.58 +        this.mLoading = true;
    1.59 +
    1.60 +      } else if (aStateFlags & nsIWebProgressListener.STATE_STOP) {
    1.61 +        this.setButtonEnabled(this.mStopButton, false);
    1.62 +        this.mStatusText.value = this.mURLBar.value + " loaded";
    1.63 +
    1.64 +        if (gRTestURLList && this.mLoading) {
    1.65 +          // Let other things happen in the first 20ms, since this
    1.66 +          // doesn't really seem to be when the page is done loading.
    1.67 +          setTimeout("gRTestURLList.doneURL()", 20);
    1.68 +        }
    1.69 +        this.mLoading = false;
    1.70 +      }
    1.71 +    },
    1.72 +
    1.73 +  onProgressChange : function(aWebProgress, aRequest,
    1.74 +                              aCurSelfProgress, aMaxSelfProgress,
    1.75 +                              aCurTotalProgress, aMaxTotalProgress)
    1.76 +    {
    1.77 +    },
    1.78 +
    1.79 +  onLocationChange : function(aWebProgress, aRequest, aLocation, aFlags)
    1.80 +    {
    1.81 +      this.mURLBar.value = aLocation.spec;
    1.82 +      this.setButtonEnabled(this.mForwardButton, gBrowser.canGoForward);
    1.83 +      this.setButtonEnabled(this.mBackButton, gBrowser.canGoBack);
    1.84 +    },
    1.85 +
    1.86 +  onStatusChange : function(aWebProgress, aRequest, aStatus, aMessage)
    1.87 +    {
    1.88 +      this.mStatusText.value = aMessage;
    1.89 +    },
    1.90 +
    1.91 +  onSecurityChange : function(aWebProgress, aRequest, aState)
    1.92 +    {
    1.93 +    },
    1.94 +
    1.95 +  // non-interface methods
    1.96 +  setButtonEnabled : function(aButtonElement, aEnabled)
    1.97 +    {
    1.98 +      if (aEnabled)
    1.99 +        aButtonElement.removeAttribute("disabled");
   1.100 +      else
   1.101 +        aButtonElement.setAttribute("disabled", "true");
   1.102 +    },
   1.103 +
   1.104 +  mStatusText : null,
   1.105 +  mURLBar : null,
   1.106 +  mForwardButton : null,
   1.107 +  mBackButton : null,
   1.108 +  mStopButton : null,
   1.109 +
   1.110 +  mLoading : false
   1.111 +
   1.112 +}
   1.113 +
   1.114 +function OnLDBLoad()
   1.115 +{
   1.116 +  gBrowser = document.getElementById("browser");
   1.117 +
   1.118 +  gProgressListener = new nsLDBBrowserContentListener();
   1.119 +  gBrowser.addProgressListener(gProgressListener);
   1.120 +
   1.121 +  gDebugger = Components.classes[NS_LAYOUT_DEBUGGINGTOOLS_CONTRACTID].
   1.122 +                  createInstance(nsILayoutDebuggingTools);
   1.123 +
   1.124 +  if (window.arguments && window.arguments[0])
   1.125 +    gBrowser.loadURI(window.arguments[0]);
   1.126 +  else
   1.127 +    gBrowser.goHome();
   1.128 +
   1.129 +  gDebugger.init(gBrowser.contentWindow);
   1.130 +
   1.131 +  checkPersistentMenus();
   1.132 +  gRTestIndexList = new RTestIndexList();
   1.133 +}
   1.134 +
   1.135 +function checkPersistentMenu(item)
   1.136 +{
   1.137 +  var menuitem = document.getElementById("menu_" + item);
   1.138 +  menuitem.setAttribute("checked", gDebugger[item]);
   1.139 +}
   1.140 +
   1.141 +function checkPersistentMenus()
   1.142 +{
   1.143 +  // Restore the toggles that are stored in prefs.
   1.144 +  checkPersistentMenu("paintFlashing");
   1.145 +  checkPersistentMenu("paintDumping");
   1.146 +  checkPersistentMenu("invalidateDumping");
   1.147 +  checkPersistentMenu("eventDumping");
   1.148 +  checkPersistentMenu("motionEventDumping");
   1.149 +  checkPersistentMenu("crossingEventDumping");
   1.150 +  checkPersistentMenu("reflowCounts");
   1.151 +}
   1.152 +
   1.153 +
   1.154 +function OnLDBUnload()
   1.155 +{
   1.156 +  gBrowser.removeProgressListener(gProgressListener);
   1.157 +}
   1.158 +
   1.159 +function toggle(menuitem)
   1.160 +{
   1.161 +  // trim the initial "menu_"
   1.162 +  var feature = menuitem.id.substring(5);
   1.163 +  gDebugger[feature] = menuitem.getAttribute("checked") == "true";
   1.164 +}
   1.165 +
   1.166 +function openFile()
   1.167 +{
   1.168 +  var nsIFilePicker = Components.interfaces.nsIFilePicker;
   1.169 +  var fp = Components.classes["@mozilla.org/filepicker;1"]
   1.170 +        .createInstance(nsIFilePicker);
   1.171 +  fp.init(window, "Select a File", nsIFilePicker.modeOpen);
   1.172 +  fp.appendFilters(nsIFilePicker.filterHTML | nsIFilePicker.filterAll);
   1.173 +  if (fp.show() == nsIFilePicker.returnOK && fp.fileURL.spec &&
   1.174 +                fp.fileURL.spec.length > 0) {
   1.175 +    gBrowser.loadURI(fp.fileURL.spec);
   1.176 +  }
   1.177 +}
   1.178 +const LDB_RDFNS = "http://mozilla.org/newlayout/LDB-rdf#";
   1.179 +const NC_RDFNS = "http://home.netscape.com/NC-rdf#";
   1.180 +
   1.181 +function RTestIndexList() {
   1.182 +  this.init();
   1.183 +}
   1.184 +
   1.185 +RTestIndexList.prototype = {
   1.186 +
   1.187 +  init : function()
   1.188 +    {
   1.189 +      const nsIPrefService = Components.interfaces.nsIPrefService;
   1.190 +      const PREF_SERVICE_CONTRACTID = "@mozilla.org/preferences-service;1";
   1.191 +      const PREF_BRANCH_NAME = "layout_debugger.rtest_url.";
   1.192 +      const nsIRDFService = Components.interfaces.nsIRDFService;
   1.193 +      const RDF_SERVICE_CONTRACTID = "@mozilla.org/rdf/rdf-service;1";
   1.194 +      const nsIRDFDataSource = Components.interfaces.nsIRDFDataSource;
   1.195 +      const RDF_DATASOURCE_CONTRACTID =
   1.196 +          "@mozilla.org/rdf/datasource;1?name=in-memory-datasource";
   1.197 +
   1.198 +      this.mPrefService = Components.classes[PREF_SERVICE_CONTRACTID].
   1.199 +                              getService(nsIPrefService);
   1.200 +      this.mPrefBranch = this.mPrefService.getBranch(PREF_BRANCH_NAME);
   1.201 +
   1.202 +      this.mRDFService = Components.classes[RDF_SERVICE_CONTRACTID].
   1.203 +                             getService(nsIRDFService);
   1.204 +      this.mDataSource = Components.classes[RDF_DATASOURCE_CONTRACTID].
   1.205 +                             createInstance(nsIRDFDataSource);
   1.206 +
   1.207 +      this.mLDB_Root = this.mRDFService.GetResource(LDB_RDFNS + "Root");
   1.208 +      this.mNC_Name = this.mRDFService.GetResource(NC_RDFNS + "name");
   1.209 +      this.mNC_Child = this.mRDFService.GetResource(NC_RDFNS + "child");
   1.210 +
   1.211 +      this.load();
   1.212 +
   1.213 +      document.getElementById("menu_RTest_baseline").database.
   1.214 +          AddDataSource(this.mDataSource);
   1.215 +      document.getElementById("menu_RTest_verify").database.
   1.216 +          AddDataSource(this.mDataSource);
   1.217 +      document.getElementById("menu_RTest_remove").database.
   1.218 +          AddDataSource(this.mDataSource);
   1.219 +    },
   1.220 +
   1.221 +  save : function()
   1.222 +    {
   1.223 +      this.mPrefBranch.deleteBranch("");
   1.224 +
   1.225 +      const nsIRDFLiteral = Components.interfaces.nsIRDFLiteral;
   1.226 +      const nsIRDFResource = Components.interfaces.nsIRDFResource;
   1.227 +      var etor = this.mDataSource.GetTargets(this.mLDB_Root,
   1.228 +                                             this.mNC_Child, true);
   1.229 +      var i = 0;
   1.230 +      while (etor.hasMoreElements()) {
   1.231 +        var resource = etor.getNext().QueryInterface(nsIRDFResource);
   1.232 +        var literal = this.mDataSource.GetTarget(resource, this.mNC_Name, true);
   1.233 +        literal = literal.QueryInterface(nsIRDFLiteral);
   1.234 +        this.mPrefBranch.setCharPref(i.toString(), literal.Value);
   1.235 +        ++i;
   1.236 +      }
   1.237 +
   1.238 +      this.mPrefService.savePrefFile(null);
   1.239 +    },
   1.240 +
   1.241 +  load : function()
   1.242 +    {
   1.243 +      var prefList = this.mPrefBranch.getChildList("");
   1.244 +
   1.245 +      var i = 0;
   1.246 +      for (var pref in prefList) {
   1.247 +        var file = this.mPrefBranch.getCharPref(pref);
   1.248 +        var resource = this.mRDFService.GetResource(file);
   1.249 +        var literal = this.mRDFService.GetLiteral(file);
   1.250 +        this.mDataSource.Assert(this.mLDB_Root, this.mNC_Child, resource, true);
   1.251 +        this.mDataSource.Assert(resource, this.mNC_Name, literal, true);
   1.252 +        ++i;
   1.253 +      }
   1.254 +
   1.255 +    },
   1.256 +
   1.257 +  /* Add a new list of regression tests to the menus. */
   1.258 +  add : function()
   1.259 +    {
   1.260 +      const nsIFilePicker = Components.interfaces.nsIFilePicker;
   1.261 +      const NS_FILEPICKER_CONTRACTID = "@mozilla.org/filepicker;1";
   1.262 +
   1.263 +      var fp = Components.classes[NS_FILEPICKER_CONTRACTID].
   1.264 +                   createInstance(nsIFilePicker);
   1.265 +
   1.266 +      // XXX l10n (but this is just for 5 developers, so no problem)
   1.267 +      fp.init(window, "New Regression Test List", nsIFilePicker.modeOpen);
   1.268 +      fp.appendFilters(nsIFilePicker.filterAll);
   1.269 +      fp.defaultString = "rtest.lst";
   1.270 +      if (fp.show() != nsIFilePicker.returnOK)
   1.271 +        return;
   1.272 +
   1.273 +      var file = fp.file.persistentDescriptor;
   1.274 +      var resource = this.mRDFService.GetResource(file);
   1.275 +      var literal = this.mRDFService.GetLiteral(file);
   1.276 +      this.mDataSource.Assert(this.mLDB_Root, this.mNC_Child, resource, true);
   1.277 +      this.mDataSource.Assert(resource, this.mNC_Name, literal, true);
   1.278 +
   1.279 +      this.save();
   1.280 +
   1.281 +    },
   1.282 +
   1.283 +  remove : function(file)
   1.284 +    {
   1.285 +      var resource = this.mRDFService.GetResource(file);
   1.286 +      var literal = this.mRDFService.GetLiteral(file);
   1.287 +      this.mDataSource.Unassert(this.mLDB_Root, this.mNC_Child, resource);
   1.288 +      this.mDataSource.Unassert(resource, this.mNC_Name, literal);
   1.289 +
   1.290 +      this.save();
   1.291 +    },
   1.292 +
   1.293 +  mPrefBranch : null,
   1.294 +  mPrefService : null,
   1.295 +  mRDFService : null,
   1.296 +  mDataSource : null,
   1.297 +  mLDB_Root : null,
   1.298 +  mNC_Child : null,
   1.299 +  mNC_Name : null
   1.300 +}
   1.301 +
   1.302 +const nsIFileInputStream = Components.interfaces.nsIFileInputStream;
   1.303 +const nsILineInputStream = Components.interfaces.nsILineInputStream;
   1.304 +const nsIFile = Components.interfaces.nsIFile;
   1.305 +const nsILocalFile = Components.interfaces.nsILocalFile;
   1.306 +const nsIFileURL = Components.interfaces.nsIFileURL;
   1.307 +const nsIIOService = Components.interfaces.nsIIOService;
   1.308 +const nsILayoutRegressionTester = Components.interfaces.nsILayoutRegressionTester;
   1.309 +
   1.310 +const NS_LOCAL_FILE_CONTRACTID = "@mozilla.org/file/local;1";
   1.311 +const IO_SERVICE_CONTRACTID = "@mozilla.org/network/io-service;1";
   1.312 +const NS_LOCALFILEINPUTSTREAM_CONTRACTID =
   1.313 +          "@mozilla.org/network/file-input-stream;1";
   1.314 +
   1.315 +
   1.316 +function RunRTest(aFilename, aIsBaseline, aIsPrinting)
   1.317 +{
   1.318 +  if (gRTestURLList) {
   1.319 +    // XXX Does alert work?
   1.320 +    alert("Already running regression test.\n");
   1.321 +    return;
   1.322 +  }
   1.323 +  dump("Running " + (aIsBaseline?"baseline":"verify") + 
   1.324 +      (aIsPrinting?" PrintMode":"") + " test for " + aFilename + ".\n");
   1.325 +
   1.326 +  var listFile = Components.classes[NS_LOCAL_FILE_CONTRACTID].
   1.327 +                    createInstance(nsILocalFile);
   1.328 +  listFile.persistentDescriptor = aFilename;
   1.329 +  gRTestURLList = new RTestURLList(listFile, aIsBaseline, aIsPrinting);
   1.330 +  gRTestURLList.startURL();
   1.331 +}
   1.332 +
   1.333 +function RTestURLList(aLocalFile, aIsBaseline, aIsPrinting) {
   1.334 +  this.init(aLocalFile, aIsBaseline, aIsPrinting);
   1.335 +}
   1.336 +
   1.337 +RTestURLList.prototype = {
   1.338 +  init : function(aLocalFile, aIsBaseline, aIsPrinting)
   1.339 +    {
   1.340 +      this.mIsBaseline = aIsBaseline;
   1.341 +      this.mIsPrinting = aIsPrinting;
   1.342 +      this.mURLs = new Array();
   1.343 +      this.readFileList(aLocalFile);
   1.344 +      this.mRegressionTester =
   1.345 +        Components.classes["@mozilla.org/layout-debug/regressiontester;1"].
   1.346 +          createInstance(nsILayoutRegressionTester)
   1.347 +    },
   1.348 +
   1.349 +  readFileList : function(aLocalFile)
   1.350 +    {
   1.351 +      var ios = Components.classes[IO_SERVICE_CONTRACTID]
   1.352 +                .getService(nsIIOService);
   1.353 +      var dirURL = ios.newFileURI(aLocalFile.parent);
   1.354 +
   1.355 +      var fis = Components.classes[NS_LOCALFILEINPUTSTREAM_CONTRACTID].
   1.356 +                    createInstance(nsIFileInputStream);
   1.357 +      fis.init(aLocalFile, -1, -1, false);
   1.358 +      var lis = fis.QueryInterface(nsILineInputStream);
   1.359 +
   1.360 +      var line = {value:null};
   1.361 +      do {
   1.362 +        var more = lis.readLine(line);
   1.363 +        var str = line.value;
   1.364 +        str = /^[^#]*/.exec(str); // strip everything after "#"
   1.365 +        str = /\S*/.exec(str); // take the first chunk of non-whitespace
   1.366 +        if (!str || str == "")
   1.367 +          continue;
   1.368 +      
   1.369 +        var item = dirURL.resolve(str);
   1.370 +        if (item.match(/\/rtest.lst$/)) {
   1.371 +          var itemurl = ios.newURI(item, null, null);
   1.372 +          itemurl = itemurl.QueryInterface(nsIFileURL);
   1.373 +          this.readFileList(itemurl.file);
   1.374 +        } else {
   1.375 +          this.mURLs.push( {url:item, dir:aLocalFile.parent, relurl:str} );
   1.376 +        }
   1.377 +      } while (more);
   1.378 +    },
   1.379 +
   1.380 +  doneURL : function()
   1.381 +  {
   1.382 +    var basename =
   1.383 +      String(this.mCurrentURL.relurl).replace(/[:=&.\/?]/g, "_") + ".rgd";
   1.384 +
   1.385 +    var data = this.mCurrentURL.dir.clone();
   1.386 +    data.append( this.mIsBaseline ? "baseline" : "verify");
   1.387 +    if (!data.exists())
   1.388 +      data.create(nsIFile.DIRECTORY_TYPE, 0777)
   1.389 +    data.append(basename);
   1.390 +
   1.391 +    dump("Writing regression data to " +
   1.392 +         data.QueryInterface(nsILocalFile).persistentDescriptor + "\n");
   1.393 +    if (this.mIsPrinting) {
   1.394 +      this.mRegressionTester.dumpFrameModel(gBrowser.contentWindow, data,
   1.395 +        nsILayoutRegressionTester.DUMP_FLAGS_MASK_PRINT_MODE);
   1.396 +    }
   1.397 +    else {
   1.398 +       this.mRegressionTester.dumpFrameModel(gBrowser.contentWindow, data, 0);
   1.399 +    }
   1.400 +     
   1.401 +      
   1.402 +
   1.403 +    if (!this.mIsBaseline) {
   1.404 +      var base_data = this.mCurrentURL.dir.clone();
   1.405 +      base_data.append("baseline");
   1.406 +      base_data.append(basename);
   1.407 +      dump("Comparing to regression data from " +
   1.408 +           base_data.QueryInterface(nsILocalFile).persistentDescriptor + "\n");
   1.409 +      var filesDiffer =
   1.410 +        this.mRegressionTester.compareFrameModels(base_data, data,
   1.411 +          nsILayoutRegressionTester.COMPARE_FLAGS_BRIEF)
   1.412 +      dump("Comparison for " + this.mCurrentURL.url + " " +
   1.413 +           (filesDiffer ? "failed" : "passed") + ".\n");
   1.414 +    }
   1.415 +
   1.416 +    this.mCurrentURL = null;
   1.417 +
   1.418 +    this.startURL();
   1.419 +  },
   1.420 +
   1.421 +  startURL : function()
   1.422 +  {
   1.423 +    this.mCurrentURL = this.mURLs.shift();
   1.424 +    if (!this.mCurrentURL) {
   1.425 +      gRTestURLList = null;
   1.426 +      return;
   1.427 +    }
   1.428 +
   1.429 +    gBrowser.loadURI(this.mCurrentURL.url);
   1.430 +  },
   1.431 +
   1.432 +  mURLs : null,
   1.433 +  mCurrentURL : null, // url (string), dir (nsIFileURL), relurl (string)
   1.434 +  mIsBaseline : null,
   1.435 +  mRegressionTester : null,
   1.436 +  mIsPrinting : null
   1.437 +}

mercurial