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 +}