merge mozilla-inbound to mozilla-central. r=merge a=merge
authorSebastian Hengst <archaeopteryx@coole-files.de>
Fri, 13 Oct 2017 23:37:41 +0200
changeset 386175 a31334a65a1c75638efae4452ecd271450df2ad0
parent 386117 684b9ee0468e6560b00c69231adfe1b7e68d58a4 (current diff)
parent 386174 d1df54aa8b21d735965c8fe7bead71cdc036f1b6 (diff)
child 386176 e89e0285e766c27b299a89004d7f7d0e01f1f879
child 386211 1199e3c98d9fd8bc3e545f0e8cbf4c6fd05be28a
child 386229 62e4765b2d97638804ca84aa75b18e60cdb9c01b
push id32676
push userarchaeopteryx@coole-files.de
push dateFri, 13 Oct 2017 21:38:18 +0000
treeherdermozilla-central@a31334a65a1c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmerge, merge
milestone58.0a1
first release with
nightly linux32
a31334a65a1c / 58.0a1 / 20171013220204 / files
nightly linux64
a31334a65a1c / 58.0a1 / 20171013220204 / files
nightly mac
a31334a65a1c / 58.0a1 / 20171013220204 / files
nightly win32
a31334a65a1c / 58.0a1 / 20171013220204 / files
nightly win64
a31334a65a1c / 58.0a1 / 20171013220204 / files
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
releases
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
merge mozilla-inbound to mozilla-central. r=merge a=merge MozReview-Commit-ID: 9adaYBJ4tlo
browser/config/tooltool-manifests/linux64/hazard.manifest
devtools/client/debugger/new/test/mochitest/browser_dbg-returnvalues.js
devtools/client/inspector/layout/components/LayoutPromoteBar.js
dom/file/tests/fileutils.js
dom/file/tests/test_fileapi.html
dom/file/tests/test_fileapi_slice.html
dom/workers/test/fileapi_chromeScript.js
dom/workers/test/test_fileReader.html
dom/workers/test/worker_fileReader.js
taskcluster/ci/test/test-sets.yml
taskcluster/ci/toolchain/linux.yml
deleted file mode 100644
--- a/browser/config/tooltool-manifests/linux64/hazard.manifest
+++ /dev/null
@@ -1,26 +0,0 @@
-[
-  {
-    "digest": "2e56a3cf84764b8e63720e5f961cff7ba8ba5cf2f353dac55c69486489bcd89f53a757e09469a07700b80cd09f09666c2db4ce375b67060ac3be967714597231",
-    "unpack": true,
-    "algorithm": "sha512",
-    "filename": "sixgill.tar.xz",
-    "size": 2629600,
-    "hg_id": "221d0d2eead9"
-  },
-  {
-    "digest": "3915f8ec396c56a8a92e6f9695b70f09ce9d1582359d1258e37e3fd43a143bc974410e4cfc27f500e095f34a8956206e0ebf799b7287f0f38def0d5e34ed71c9",
-    "unpack": true,
-    "setup": "setup.sh",
-    "algorithm": "sha512",
-    "filename": "gtk3.tar.xz",
-    "size": 12072532
-  },
-  {
-    "version": "rustc 1.19.0 (0ade33941 2017-07-17) repack",
-    "size": 161014632,
-    "digest": "65bebcf94fc66ea618c58c9ac33f0f206095ecfe3931cc6edb301f4b40480e3b44b0f39aea7a25fed8eef47e63523e7e670082947a3662cdc04c68ebbe5dfc89",
-    "algorithm": "sha512",
-    "filename": "rustc.tar.xz",
-    "unpack": true
-  }
-]
--- a/browser/extensions/pdfjs/README.mozilla
+++ b/browser/extensions/pdfjs/README.mozilla
@@ -1,5 +1,5 @@
 This is the PDF.js project output, https://github.com/mozilla/pdf.js
 
-Current extension version is: 1.9.630
+Current extension version is: 1.9.640
 
-Taken from upstream commit: ec469673
+Taken from upstream commit: 853db85b
--- a/browser/extensions/pdfjs/content/build/pdf.js
+++ b/browser/extensions/pdfjs/content/build/pdf.js
@@ -1985,17 +1985,17 @@ function getDocument(src, pdfDataRangeTr
     });
   }).catch(task._capability.reject);
   return task;
 }
 function _fetchDocument(worker, source, pdfDataRangeTransport, docId) {
   if (worker.destroyed) {
     return Promise.reject(new Error('Worker was destroyed'));
   }
-  let apiVersion = '1.9.630';
+  let apiVersion = '1.9.640';
   source.disableAutoFetch = (0, _dom_utils.getDefaultSetting)('disableAutoFetch');
   source.disableStream = (0, _dom_utils.getDefaultSetting)('disableStream');
   source.chunkedViewerLoading = !!pdfDataRangeTransport;
   if (pdfDataRangeTransport) {
     source.length = pdfDataRangeTransport.length;
     source.initialData = pdfDataRangeTransport.initialData;
   }
   return worker.messageHandler.sendWithPromise('GetDocRequest', {
@@ -2879,17 +2879,17 @@ var WorkerTransport = function WorkerTra
             if ((0, _dom_utils.getDefaultSetting)('pdfBug') && _global_scope2.default.FontInspector && _global_scope2.default['FontInspector'].enabled) {
               fontRegistry = {
                 registerFont(font, url) {
                   _global_scope2.default['FontInspector'].fontAdded(font, url);
                 }
               };
             }
             var font = new _font_loader.FontFaceObject(exportedData, {
-              isEvalSuported: (0, _dom_utils.getDefaultSetting)('isEvalSupported'),
+              isEvalSupported: (0, _dom_utils.getDefaultSetting)('isEvalSupported'),
               disableFontFace: (0, _dom_utils.getDefaultSetting)('disableFontFace'),
               fontRegistry
             });
             var fontReady = fontObjs => {
               this.commonObjs.resolve(id, font);
             };
             this.fontLoader.bind([font], fontReady);
             break;
@@ -3306,18 +3306,18 @@ var _UnsupportedManager = function Unsup
       for (var i = 0, ii = listeners.length; i < ii; i++) {
         listeners[i](featureId);
       }
     }
   };
 }();
 var version, build;
 {
-  exports.version = version = '1.9.630';
-  exports.build = build = 'ec469673';
+  exports.version = version = '1.9.640';
+  exports.build = build = '853db85b';
 }
 exports.getDocument = getDocument;
 exports.LoopbackPort = LoopbackPort;
 exports.PDFDataRangeTransport = PDFDataRangeTransport;
 exports.PDFWorker = PDFWorker;
 exports.PDFDocumentProxy = PDFDocumentProxy;
 exports.PDFPageProxy = PDFPageProxy;
 exports.setPDFNetworkStreamClass = setPDFNetworkStreamClass;
@@ -5046,18 +5046,18 @@ exports.SVGGraphics = SVGGraphics;
 
 /***/ }),
 /* 9 */
 /***/ (function(module, exports, __w_pdfjs_require__) {
 
 "use strict";
 
 
-var pdfjsVersion = '1.9.630';
-var pdfjsBuild = 'ec469673';
+var pdfjsVersion = '1.9.640';
+var pdfjsBuild = '853db85b';
 var pdfjsSharedUtil = __w_pdfjs_require__(0);
 var pdfjsDisplayGlobal = __w_pdfjs_require__(13);
 var pdfjsDisplayAPI = __w_pdfjs_require__(3);
 var pdfjsDisplayTextLayer = __w_pdfjs_require__(7);
 var pdfjsDisplayAnnotationLayer = __w_pdfjs_require__(6);
 var pdfjsDisplayDOMUtils = __w_pdfjs_require__(1);
 var pdfjsDisplaySVG = __w_pdfjs_require__(8);
 ;
@@ -8172,18 +8172,18 @@ var _svg = __w_pdfjs_require__(8);
 
 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
 
 if (!_global_scope2.default.PDFJS) {
   _global_scope2.default.PDFJS = {};
 }
 var PDFJS = _global_scope2.default.PDFJS;
 {
-  PDFJS.version = '1.9.630';
-  PDFJS.build = 'ec469673';
+  PDFJS.version = '1.9.640';
+  PDFJS.build = '853db85b';
 }
 PDFJS.pdfBug = false;
 if (PDFJS.verbosity !== undefined) {
   (0, _util.setVerbosityLevel)(PDFJS.verbosity);
 }
 delete PDFJS.verbosity;
 Object.defineProperty(PDFJS, 'verbosity', {
   get() {
--- a/browser/extensions/pdfjs/content/build/pdf.worker.js
+++ b/browser/extensions/pdfjs/content/build/pdf.worker.js
@@ -16414,52 +16414,62 @@ var PartialEvaluator = function PartialE
           if (!preprocessor.read(operation)) {
             break;
           }
           var args = operation.args;
           var fn = operation.fn;
           switch (fn | 0) {
             case _util.OPS.paintXObject:
               var name = args[0].name;
-              if (!name) {
-                (0, _util.warn)('XObject must be referred to by name.');
-                continue;
-              }
-              if (imageCache[name] !== undefined) {
+              if (name && imageCache[name] !== undefined) {
                 operatorList.addOp(imageCache[name].fn, imageCache[name].args);
                 args = null;
                 continue;
               }
-              var xobj = xobjs.get(name);
-              if (xobj) {
+              next(new Promise(function (resolveXObject, rejectXObject) {
+                if (!name) {
+                  throw new _util.FormatError('XObject must be referred to by name.');
+                }
+                let xobj = xobjs.get(name);
+                if (!xobj) {
+                  operatorList.addOp(fn, args);
+                  resolveXObject();
+                  return;
+                }
                 if (!(0, _primitives.isStream)(xobj)) {
                   throw new _util.FormatError('XObject should be a stream');
                 }
-                var type = xobj.dict.get('Subtype');
+                let type = xobj.dict.get('Subtype');
                 if (!(0, _primitives.isName)(type)) {
                   throw new _util.FormatError('XObject should have a Name subtype');
                 }
                 if (type.name === 'Form') {
                   stateManager.save();
-                  next(self.buildFormXObject(resources, xobj, null, operatorList, task, stateManager.state.clone()).then(function () {
+                  self.buildFormXObject(resources, xobj, null, operatorList, task, stateManager.state.clone()).then(function () {
                     stateManager.restore();
-                  }));
+                    resolveXObject();
+                  }, rejectXObject);
                   return;
                 } else if (type.name === 'Image') {
                   self.buildPaintImageXObject(resources, xobj, false, operatorList, name, imageCache);
-                  args = null;
-                  continue;
                 } else if (type.name === 'PS') {
                   (0, _util.info)('Ignored XObject subtype PS');
-                  continue;
                 } else {
                   throw new _util.FormatError(`Unhandled XObject subtype ${type.name}`);
                 }
-              }
-              break;
+                resolveXObject();
+              }).catch(function (reason) {
+                if (self.options.ignoreErrors) {
+                  self.handler.send('UnsupportedFeature', { featureId: _util.UNSUPPORTED_FEATURES.unknown });
+                  (0, _util.warn)(`getOperatorList - ignoring XObject: "${reason}".`);
+                  return;
+                }
+                throw reason;
+              }));
+              return;
             case _util.OPS.setFont:
               var fontSize = args[1];
               next(self.handleSetFont(resources, args, null, operatorList, task, stateManager.state).then(function (loadedName) {
                 operatorList.addDependency(loadedName);
                 operatorList.addOp(_util.OPS.setFont, [loadedName, fontSize]);
               }));
               return;
             case _util.OPS.endInlineImage:
@@ -16998,67 +17008,84 @@ var PartialEvaluator = function PartialE
               buildTextContentItem(args[2]);
               break;
             case _util.OPS.paintXObject:
               flushTextContentItem();
               if (!xobjs) {
                 xobjs = resources.get('XObject') || _primitives.Dict.empty;
               }
               var name = args[0].name;
-              if (name in skipEmptyXObjs) {
-                break;
-              }
-              var xobj = xobjs.get(name);
-              if (!xobj) {
-                break;
-              }
-              if (!(0, _primitives.isStream)(xobj)) {
-                throw new _util.FormatError('XObject should be a stream');
-              }
-              var type = xobj.dict.get('Subtype');
-              if (!(0, _primitives.isName)(type)) {
-                throw new _util.FormatError('XObject should have a Name subtype');
-              }
-              if (type.name !== 'Form') {
-                skipEmptyXObjs[name] = true;
-                break;
-              }
-              var currentState = stateManager.state.clone();
-              var xObjStateManager = new StateManager(currentState);
-              var matrix = xobj.dict.getArray('Matrix');
-              if (Array.isArray(matrix) && matrix.length === 6) {
-                xObjStateManager.transform(matrix);
-              }
-              enqueueChunk();
-              let sinkWrapper = {
-                enqueueInvoked: false,
-                enqueue(chunk, size) {
-                  this.enqueueInvoked = true;
-                  sink.enqueue(chunk, size);
-                },
-                get desiredSize() {
-                  return sink.desiredSize;
-                },
-                get ready() {
-                  return sink.ready;
-                }
-              };
-              next(self.getTextContent({
-                stream: xobj,
-                task,
-                resources: xobj.dict.get('Resources') || resources,
-                stateManager: xObjStateManager,
-                normalizeWhitespace,
-                combineTextItems,
-                sink: sinkWrapper,
-                seenStyles
-              }).then(function () {
-                if (!sinkWrapper.enqueueInvoked) {
+              if (name && skipEmptyXObjs[name] !== undefined) {
+                break;
+              }
+              next(new Promise(function (resolveXObject, rejectXObject) {
+                if (!name) {
+                  throw new _util.FormatError('XObject must be referred to by name.');
+                }
+                let xobj = xobjs.get(name);
+                if (!xobj) {
+                  resolveXObject();
+                  return;
+                }
+                if (!(0, _primitives.isStream)(xobj)) {
+                  throw new _util.FormatError('XObject should be a stream');
+                }
+                let type = xobj.dict.get('Subtype');
+                if (!(0, _primitives.isName)(type)) {
+                  throw new _util.FormatError('XObject should have a Name subtype');
+                }
+                if (type.name !== 'Form') {
                   skipEmptyXObjs[name] = true;
-                }
+                  resolveXObject();
+                  return;
+                }
+                let currentState = stateManager.state.clone();
+                let xObjStateManager = new StateManager(currentState);
+                let matrix = xobj.dict.getArray('Matrix');
+                if (Array.isArray(matrix) && matrix.length === 6) {
+                  xObjStateManager.transform(matrix);
+                }
+                enqueueChunk();
+                let sinkWrapper = {
+                  enqueueInvoked: false,
+                  enqueue(chunk, size) {
+                    this.enqueueInvoked = true;
+                    sink.enqueue(chunk, size);
+                  },
+                  get desiredSize() {
+                    return sink.desiredSize;
+                  },
+                  get ready() {
+                    return sink.ready;
+                  }
+                };
+                self.getTextContent({
+                  stream: xobj,
+                  task,
+                  resources: xobj.dict.get('Resources') || resources,
+                  stateManager: xObjStateManager,
+                  normalizeWhitespace,
+                  combineTextItems,
+                  sink: sinkWrapper,
+                  seenStyles
+                }).then(function () {
+                  if (!sinkWrapper.enqueueInvoked) {
+                    skipEmptyXObjs[name] = true;
+                  }
+                  resolveXObject();
+                }, rejectXObject);
+              }).catch(function (reason) {
+                if (reason instanceof _util.AbortException) {
+                  return;
+                }
+                if (self.options.ignoreErrors) {
+                  (0, _util.warn)(`getTextContent - ignoring XObject: "${reason}".`);
+                  return;
+                }
+                throw reason;
               }));
               return;
             case _util.OPS.setGState:
               flushTextContentItem();
               var dictName = args[0];
               var extGState = resources.get('ExtGState');
               if (!(0, _primitives.isDict)(extGState) || !(0, _primitives.isName)(dictName)) {
                 break;
@@ -23818,18 +23845,18 @@ exports.PostScriptCompiler = PostScriptC
 
 /***/ }),
 /* 17 */
 /***/ (function(module, exports, __w_pdfjs_require__) {
 
 "use strict";
 
 
-var pdfjsVersion = '1.9.630';
-var pdfjsBuild = 'ec469673';
+var pdfjsVersion = '1.9.640';
+var pdfjsBuild = '853db85b';
 var pdfjsCoreWorker = __w_pdfjs_require__(18);
 exports.WorkerMessageHandler = pdfjsCoreWorker.WorkerMessageHandler;
 
 /***/ }),
 /* 18 */
 /***/ (function(module, exports, __w_pdfjs_require__) {
 
 "use strict";
@@ -24014,17 +24041,17 @@ var WorkerMessageHandler = {
     });
   },
   createDocumentHandler(docParams, port) {
     var pdfManager;
     var terminated = false;
     var cancelXHRs = null;
     var WorkerTasks = [];
     let apiVersion = docParams.apiVersion;
-    let workerVersion = '1.9.630';
+    let workerVersion = '1.9.640';
     if (apiVersion !== null && apiVersion !== workerVersion) {
       throw new Error(`The API version "${apiVersion}" does not match ` + `the Worker version "${workerVersion}".`);
     }
     var docId = docParams.docId;
     var docBaseUrl = docParams.docBaseUrl;
     var workerHandlerName = docParams.docId + '_worker';
     var handler = new _util.MessageHandler(workerHandlerName, docId, port);
     handler.postMessageTransfers = docParams.postMessageTransfers;
--- a/browser/extensions/pdfjs/content/web/viewer.js
+++ b/browser/extensions/pdfjs/content/web/viewer.js
@@ -1498,20 +1498,27 @@ let PDFViewerApplication = {
       this.toolbar.setPagesCount(pdfDocument.numPages, true);
       this.toolbar.setPageNumber(pdfViewer.currentPageNumber, pdfViewer.currentPageLabel);
     });
     pagesPromise.then(() => {
       if (!this.supportsPrinting) {
         return;
       }
       pdfDocument.getJavaScript().then(javaScript => {
-        if (javaScript.length) {
+        if (javaScript.length === 0) {
+          return;
+        }
+        javaScript.some(js => {
+          if (!js) {
+            return false;
+          }
           console.warn('Warning: JavaScript is not supported');
           this.fallback(_pdfjsLib.UNSUPPORTED_FEATURES.javaScript);
-        }
+          return true;
+        });
         let regex = /\bprint\s*\(/;
         for (let i = 0, ii = javaScript.length; i < ii; i++) {
           let js = javaScript[i];
           if (js && regex.test(js)) {
             setTimeout(function () {
               window.print();
             });
             return;
@@ -4376,17 +4383,17 @@ exports.PDFFindBar = PDFFindBar;
 /***/ (function(module, exports, __webpack_require__) {
 
 "use strict";
 
 
 Object.defineProperty(exports, "__esModule", {
   value: true
 });
-exports.isDestsEqual = exports.PDFHistory = undefined;
+exports.isDestArraysEqual = exports.isDestHashesEqual = exports.PDFHistory = undefined;
 
 var _ui_utils = __webpack_require__(0);
 
 var _dom_events = __webpack_require__(2);
 
 const HASH_CHANGE_TIMEOUT = 1000;
 const POSITION_UPDATED_THRESHOLD = 50;
 const UPDATE_VIEWAREA_TIMEOUT = 1000;
@@ -4479,17 +4486,17 @@ class PDFHistory {
       console.error('PDFHistory.push: Invalid parameters.');
       return;
     }
     let hash = namedDest || JSON.stringify(explicitDest);
     if (!hash) {
       return;
     }
     let forceReplace = false;
-    if (this._destination && (this._destination.hash === hash || isDestsEqual(this._destination.dest, explicitDest))) {
+    if (this._destination && (isDestHashesEqual(this._destination.hash, hash) || isDestArraysEqual(this._destination.dest, explicitDest))) {
       if (this._destination.page) {
         return;
       }
       forceReplace = true;
     }
     if (this._popStateInProgress && !forceReplace) {
       return;
     }
@@ -4686,17 +4693,30 @@ class PDFHistory {
         this._tryPushCurrentPosition();
       }
     };
     eventBus.on('updateviewarea', _boundEvents.updateViewarea);
     window.addEventListener('popstate', _boundEvents.popState);
     window.addEventListener('pagehide', _boundEvents.pageHide);
   }
 }
-function isDestsEqual(firstDest, secondDest) {
+function isDestHashesEqual(destHash, pushHash) {
+  if (typeof destHash !== 'string' || typeof pushHash !== 'string') {
+    return false;
+  }
+  if (destHash === pushHash) {
+    return true;
+  }
+  let { nameddest } = (0, _ui_utils.parseQueryString)(destHash);
+  if (nameddest === pushHash) {
+    return true;
+  }
+  return false;
+}
+function isDestArraysEqual(firstDest, secondDest) {
   function isEntryEqual(first, second) {
     if (typeof first !== typeof second) {
       return false;
     }
     if (first instanceof Array || second instanceof Array) {
       return false;
     }
     if (first !== null && typeof first === 'object' && second !== null) {
@@ -4721,17 +4741,18 @@ function isDestsEqual(firstDest, secondD
   for (let i = 0, ii = firstDest.length; i < ii; i++) {
     if (!isEntryEqual(firstDest[i], secondDest[i])) {
       return false;
     }
   }
   return true;
 }
 exports.PDFHistory = PDFHistory;
-exports.isDestsEqual = isDestsEqual;
+exports.isDestHashesEqual = isDestHashesEqual;
+exports.isDestArraysEqual = isDestArraysEqual;
 
 /***/ }),
 /* 17 */
 /***/ (function(module, exports, __webpack_require__) {
 
 "use strict";
 
 
@@ -6438,19 +6459,23 @@ class AnnotationLayerBuilder {
   constructor({ pageDiv, pdfPage, linkService, downloadManager, renderInteractiveForms = false, l10n = _ui_utils.NullL10n }) {
     this.pageDiv = pageDiv;
     this.pdfPage = pdfPage;
     this.linkService = linkService;
     this.downloadManager = downloadManager;
     this.renderInteractiveForms = renderInteractiveForms;
     this.l10n = l10n;
     this.div = null;
+    this._cancelled = false;
   }
   render(viewport, intent = 'display') {
     this.pdfPage.getAnnotations({ intent }).then(annotations => {
+      if (this._cancelled) {
+        return;
+      }
       let parameters = {
         viewport: viewport.clone({ dontFlip: true }),
         div: this.div,
         annotations,
         page: this.pdfPage,
         renderInteractiveForms: this.renderInteractiveForms,
         linkService: this.linkService,
         downloadManager: this.downloadManager
@@ -6465,16 +6490,19 @@ class AnnotationLayerBuilder {
         this.div.className = 'annotationLayer';
         this.pageDiv.appendChild(this.div);
         parameters.div = this.div;
         _pdfjsLib.AnnotationLayer.render(parameters);
         this.l10n.translate(this.div);
       }
     });
   }
+  cancel() {
+    this._cancelled = true;
+  }
   hide() {
     if (!this.div) {
       return;
     }
     this.div.setAttribute('hidden', 'true');
   }
 }
 class DefaultAnnotationLayerFactory {
@@ -6573,34 +6601,35 @@ class PDFPageView {
     zoomLayerCanvas.width = 0;
     zoomLayerCanvas.height = 0;
     if (removeFromDOM) {
       this.zoomLayer.remove();
     }
     this.zoomLayer = null;
   }
   reset(keepZoomLayer = false, keepAnnotations = false) {
-    this.cancelRendering();
+    this.cancelRendering(keepAnnotations);
     let div = this.div;
     div.style.width = Math.floor(this.viewport.width) + 'px';
     div.style.height = Math.floor(this.viewport.height) + 'px';
     let childNodes = div.childNodes;
     let currentZoomLayerNode = keepZoomLayer && this.zoomLayer || null;
     let currentAnnotationNode = keepAnnotations && this.annotationLayer && this.annotationLayer.div || null;
     for (let i = childNodes.length - 1; i >= 0; i--) {
       let node = childNodes[i];
       if (currentZoomLayerNode === node || currentAnnotationNode === node) {
         continue;
       }
       div.removeChild(node);
     }
     div.removeAttribute('data-loaded');
     if (currentAnnotationNode) {
       this.annotationLayer.hide();
-    } else {
+    } else if (this.annotationLayer) {
+      this.annotationLayer.cancel();
       this.annotationLayer = null;
     }
     if (!currentZoomLayerNode) {
       if (this.canvas) {
         this.paintedViewportMap.delete(this.canvas);
         this.canvas.width = 0;
         this.canvas.height = 0;
         delete this.canvas;
@@ -6656,27 +6685,31 @@ class PDFPageView {
         this.zoomLayer.style.position = 'absolute';
       }
     }
     if (this.zoomLayer) {
       this.cssTransform(this.zoomLayer.firstChild);
     }
     this.reset(true, true);
   }
-  cancelRendering() {
+  cancelRendering(keepAnnotations = false) {
     if (this.paintTask) {
       this.paintTask.cancel();
       this.paintTask = null;
     }
     this.renderingState = _pdf_rendering_queue.RenderingStates.INITIAL;
     this.resume = null;
     if (this.textLayer) {
       this.textLayer.cancel();
       this.textLayer = null;
     }
+    if (!keepAnnotations && this.annotationLayer) {
+      this.annotationLayer.cancel();
+      this.annotationLayer = null;
+    }
   }
   cssTransform(target, redrawAnnotations = false) {
     let width = this.viewport.width;
     let height = this.viewport.height;
     let div = this.div;
     target.style.width = target.parentNode.style.width = div.style.width = Math.floor(width) + 'px';
     target.style.height = target.parentNode.style.height = div.style.height = Math.floor(height) + 'px';
     let relativeRotation = this.viewport.rotation - this.paintedViewportMap.get(target).rotation;
--- a/devtools/client/debugger/new/README.mozilla
+++ b/devtools/client/debugger/new/README.mozilla
@@ -1,11 +1,11 @@
 This is the debugger.html project output.
 See https://github.com/devtools-html/debugger.html
 
-Taken from upstream commit: 6d850d386e2dfef08077602191808fd5c3d8b1ee
+Taken from upstream commit: 455e7e3f2de29113e37de8c03052de110f5fb106
 
 Packages:
 - babel-plugin-transform-es2015-modules-commonjs @6.26.0
 - babel-preset-react @6.24.1
 - react @15.6.2
 - react-dom @15.6.2
-- webpack @3.6.0
+- webpack @3.7.1
--- a/devtools/client/debugger/new/debugger.css
+++ b/devtools/client/debugger/new/debugger.css
@@ -31,17 +31,17 @@
 
 .landing-page .panel header {
   display: flex;
   align-items: baseline;
   margin: calc(2 * var(--base-spacing)) 0 0;
   padding-bottom: var(--base-spacing);
 }
 
-.landing-page .panel header input[type=search] {
+.landing-page .panel header input[type="search"] {
   flex: 1;
   background-color: var(--theme-tab-toolbar-background);
   color: var(--theme-comment);
   font-size: var(--ui-element-font-size);
   border: 1px solid var(--theme-splitter-color);
   padding: calc(var(--base-spacing) / 2);
   margin: 0 var(--base-spacing);
   transition: var(--base-transition);
@@ -110,23 +110,21 @@
 }
 
 .landing-page .panel .under-construction {
   display: flex;
   width: 417px;
   color: var(--theme-comment);
   font-size: calc(var(--ui-element-font-size) / 1);
   margin: var(--base-spacing) auto;
+  max-width: 350px;
+
   line-height: 1.4em;
 }
 
-.landing-page .panel .under-construction .under-construction-message {
-  max-width: 350px;
-}
-
 .landing-page .panel .under-construction .github-link {
   display: block;
 }
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 .landing-page .tab-group {
@@ -250,34 +248,37 @@
   border-top: 2px solid var(--theme-splitter-color);
   margin: 2px;
 }
 
 .landing-page .sidebar .title-wrapper .launchpad-container {
   padding-left: var(--base-spacing);
 }
 
-.landing-page .sidebar .title-wrapper  .launchpad-container .launchpad-container-icon {
+.landing-page
+  .sidebar
+  .title-wrapper
+  .launchpad-container
+  .launchpad-container-icon {
   display: inline-block;
 }
 
-.landing-page .sidebar .title-wrapper  .launchpad-container svg {
-  width: 24px;
-  height: 24px;
-}
-
-.landing-page .sidebar .title-wrapper  .launchpad-container svg path {
-  width: 24px;
-  height: 24px;
-  fill: var(--theme-body-color);
-}
-
-.landing-page .sidebar .title-wrapper .launchpad-container .launchpad-container-title {
+.landing-page .sidebar .title-wrapper .launchpad-container .rocket svg {
+  width: 18px;
+  height: 18px;
+}
+
+.landing-page
+  .sidebar
+  .title-wrapper
+  .launchpad-container
+  .launchpad-container-title {
   display: inline;
   padding-left: 3px;
+  font-weight: normal;
 }
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 menu {
   display: inline;
   padding: 0;
@@ -496,16 +497,22 @@ body {
 .shortcuts-list li {
   font-size: 12px;
   color: var(--theme-body-color);
   padding-top: 5px;
   display: flex;
   justify-content: space-between;
   border: 1px solid transparent;
 }
+
+@media (max-width: 640px) {
+  .shortcuts-section {
+    width: 100%;
+  }
+}
 :root {
   --arrow-width: 10px;
 }
 
 :root.theme-light,
 :root .theme-light {
   --search-overlays-semitransparent: rgba(221, 225, 228, 0.66);
   --popup-shadow-color: #d0d0d0;
@@ -937,21 +944,28 @@ menuseparator {
 .domain svg,
 .folder svg,
 .refresh svg,
 .shortcut svg,
 .worker svg {
   margin-inline-end: 5px;
 }
 
-.arrow svg {
-  fill: var(--theme-splitter-color);
+img.arrow {
+  mask: url("chrome://devtools/skin/images/debugger/arrow.svg");
   margin-top: 3px;
-  transition: transform 0.25s ease;
-  width: 10px;
+  width: 9px;
+  height: 9px;
+  padding-top: 9px;
+  background: var(--theme-splitter-color);
+  mask-size: 100%;
+  display: inline-block;
+  margin-bottom: 1px;
+  transform: rotate(-90deg);
+  transition: transform 0.18s ease;
 }
 
 html:not([dir="rtl"]) .arrow svg {
   margin-right: 5px;
   transform: rotate(-90deg);
 }
 
 html[dir="rtl"] .arrow svg {
@@ -1436,22 +1450,30 @@ html[dir="rtl"] .managed-tree .tree .nod
   overflow-x: hidden;
   overflow-y: auto;
 }
 
 .sources-list .managed-tree .tree .node {
   padding: 0px 0px 0px 3px;
 }
 
-.sources-list .tree .arrow svg {
-  margin-top: 0px;
-}
-
-.theme-dark .sources-list .tree .node:not(.focused) svg {
-  fill: var(--theme-content-color3);
+.sources-list .tree img.arrow {
+  margin-right: 5px;
+}
+
+.sources-list .tree .focused img.arrow {
+  background-color: white;
+}
+
+.sources-list .tree img.arrow.expanded {
+  transform: rotate(0deg);
+}
+
+.theme-dark .sources-list .tree .node:not(.focused) img.arrow {
+  background: var(--theme-content-color3);
 }
 
 .theme-dark .source-list .tree .node.focused {
   background-color: var(--theme-tab-toolbar-background);
 }
 
 .sources-list .tree .focused .label {
   background-color: var(--theme-selection-background);
@@ -1463,22 +1485,22 @@ html[dir="rtl"] .managed-tree .tree .nod
 }
 
 .sources-list .tree .node .no-arrow {
   width: 10px;
   display: inline-block;
 }
 
 .no-sources-message {
+  width: 100%;
+  font-style: italic;
+  text-align: center;
+  padding: 0.5em;
   font-size: 12px;
-  color: var(--theme-comment-alt);
-  font-weight: lighter;
-  padding-top: 5px;
-  flex-grow: 1;
-  display: flex;
+  user-select: none;
   justify-content: center;
   align-items: center;
 }
 
 .sources-panel .outline {
   display: flex;
   flex: 1;
 }
--- a/devtools/client/debugger/new/debugger.js
+++ b/devtools/client/debugger/new/debugger.js
@@ -4567,61 +4567,62 @@ var _require7 = __webpack_require__(885)
     chrome = _require7.chrome,
     startDebugging = _require7.startDebugging;
 
 var Root = __webpack_require__(186);
 
 // Using this static variable allows webpack to know at compile-time
 // to avoid this require and not include it at all in the output.
 if (false) {
-  require("devtools-modules/src/themes/light-theme.css");
-  require("devtools-modules/src/themes/dark-theme.css");
-  require("devtools-modules/src/themes/firebug-theme.css");
-}
-
-function updateTheme() {
+  require("devtools-mc-assets/assets/devtools/client/themes/light-theme.css");
+  require("devtools-mc-assets/assets/devtools/client/themes/dark-theme.css");
+  require("devtools-mc-assets/assets/devtools/client/themes/firebug-theme.css");
+}
+
+function updateTheme(className) {
   if (false) {
     var theme = getValue("theme");
     var root = document.body.parentNode;
     var appRoot = document.querySelector(".launchpad-root");
 
     root.className = "";
-    appRoot.className = "launchpad-root";
+    appRoot.className = className;
 
     root.classList.add(`theme-${theme}`);
     appRoot.classList.add(`theme-${theme}`);
   }
 }
 
 function updateDir() {
   var dir = getValue("dir");
   var root = document.body.parentNode;
   root.dir = dir;
 }
 
-function renderRoot(_React, _ReactDOM, component, _store) {
+function renderRoot(_React, _ReactDOM, component, _store, props) {
   var createElement = _React.createElement;
 
   var mount = document.querySelector("#mount");
 
   // bail in test environments that do not have a mount
   if (!mount) {
     return;
   }
 
-  var root = Root("launchpad-root theme-body");
+  var className = "launchpad-root theme-body";
+  var root = Root(className);
   mount.appendChild(root);
 
   if (isDevelopment()) {
     updateConfig();
-    updateTheme();
+    updateTheme(className);
   }
 
   if (component.props || component.propTypes) {
-    _ReactDOM.render(createElement(Provider, { store: _store }, createElement(component)), root);
+    _ReactDOM.render(createElement(Provider, { store: _store }, createElement(component, props)), root);
   } else {
     root.appendChild(component);
   }
 }
 
 function unmountRoot(_ReactDOM) {
   var mount = document.querySelector("#mount .launchpad-root");
   _ReactDOM.unmountComponentAtNode(mount);
@@ -11890,17 +11891,17 @@ module.exports = {
 
 
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 var React = __webpack_require__(0);
 
-__webpack_require__(1221);
+__webpack_require__(1298);
 var dom = React.DOM;
 
 var ImPropTypes = __webpack_require__(150);
 var configMap = __webpack_require__(145).sidePanelItems;
 var Tabs = React.createFactory(__webpack_require__(172));
 var Sidebar = React.createFactory(__webpack_require__(176));
 var Settings = React.createFactory(__webpack_require__(179));
 
@@ -11971,28 +11972,26 @@ var LandingPage = React.createClass({
     }
 
     var connectedStateText = isNodeSelected ? null : `Please open a tab in ${name}`;
 
     return isConnected ? connectedStateText : this.renderLaunchButton(name, isUnderConstruction);
   },
 
   renderLaunchButton(browserName, isUnderConstruction) {
-    return dom.div({ className: "launch-action-container" }, dom.button({ onClick: () => this.launchBrowser(browserName) }, `Launch ${browserName}`), isUnderConstruction ? this.renderExperimentalMessage(browserName) // eslint-disable-line max-len
-    : null);
+    return dom.div({ className: "launch-action-container" }, dom.button({ onClick: () => this.launchBrowser(browserName) }, `Launch ${browserName}`), isUnderConstruction ? this.renderExperimentalMessage(browserName) : null);
   },
 
   renderExperimentalMessage(browserName) {
     var underConstructionMessage = "Debugging is experimental and certain features won't work (i.e, seeing variables, attaching breakpoints)"; // eslint-disable-line max-len
-    var githubIssuesUrl = "https://github.com/devtools-html/debugger.html/issues?q=is%3Aopen+is%3Aissue+label%3A";
-    var underConstructionImageSrc = __webpack_require__(855);
-    return dom.div({ className: "under-construction" }, dom.img({ src: underConstructionImageSrc }), dom.div({ className: "under-construction-message" }, underConstructionMessage, // eslint-disable-line max-len
-    dom.a({ className: "github-link",
-      href: `${githubIssuesUrl}${browserName}`,
-      target: "_blank" }, "Help us make it happen")));
+
+    return dom.div({ className: "under-construction" }, dom.div({ className: "under-construction-message" }, dom.p({}, underConstructionMessage), dom.img({ src: "/assets/under_construction.png" }), dom.a({
+      className: "github-link",
+      target: "_blank"
+    }, "Help us make it happen")));
   },
 
   launchBrowser(browser) {
     fetch("/launch", {
       body: JSON.stringify({ browser }),
       headers: {
         "Content-Type": "application/json"
       },
@@ -12317,17 +12316,17 @@ function combineReducers(reducers) {
 
 
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 var React = __webpack_require__(0);
 
-__webpack_require__(1222);
+__webpack_require__(1299);
 var dom = React.DOM;
 
 var classnames = __webpack_require__(175);
 
 function getTabURL(tab, paramName) {
   var tabID = tab.get("id");
   return `/?${paramName}=${tabID}`;
 }
@@ -12552,42 +12551,34 @@ var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBP
 "use strict";
 
 
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 var React = __webpack_require__(0);
-var createElement = React.createElement;
-
-__webpack_require__(1223);
-var rocketSvg = __webpack_require__(1126);
-var InlineSVG = __webpack_require__(1205);
-
+__webpack_require__(1300);
 var dom = React.DOM;
 
 var classnames = __webpack_require__(175);
-
+var Svg = __webpack_require__(1349);
 var Sidebar = React.createClass({
   displayName: "Sidebar",
 
   propTypes: {
     supportsFirefox: React.PropTypes.bool.isRequired,
     supportsChrome: React.PropTypes.bool.isRequired,
     title: React.PropTypes.string.isRequired,
     selectedPane: React.PropTypes.string.isRequired,
     onSideBarItemClick: React.PropTypes.func.isRequired
   },
 
   renderTitle(title) {
-    return dom.div({ className: "title-wrapper" }, dom.h1({}, title), dom.div({ className: "launchpad-container" }, createElement(InlineSVG, {
-      className: "launchpad-container-icon",
-      src: rocketSvg
-    }), dom.h2({ className: "launchpad-container-title" }, "Launchpad")));
+    return dom.div({ className: "title-wrapper" }, dom.h1({}, title), dom.div({ className: "launchpad-container" }, Svg({ name: "rocket" }), dom.h2({ className: "launchpad-container-title" }, "Launchpad")));
   },
 
   renderItem(title) {
     return dom.li({
       className: classnames({
         selected: title == this.props.selectedPane
       }),
       key: title,
@@ -13216,17 +13207,17 @@ module.exports = {
 "use strict";
 
 
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 var classnames = __webpack_require__(175);
-__webpack_require__(1225);
+__webpack_require__(1302);
 
 module.exports = function (className) {
   var root = document.createElement("div");
   root.className = classnames(className);
   root.style.setProperty("flex", 1);
   return root;
 };
 
@@ -16047,23 +16038,23 @@ var _actions2 = _interopRequireDefault(_
 var _ShortcutsModal = __webpack_require__(1181);
 
 var _selectors = __webpack_require__(242);
 
 var _ui = __webpack_require__(1128);
 
 var _devtoolsModules = __webpack_require__(830);
 
-__webpack_require__(1228);
-
-__webpack_require__(1229);
-
-__webpack_require__(1230);
-
-__webpack_require__(1231);
+__webpack_require__(1305);
+
+__webpack_require__(1306);
+
+__webpack_require__(1307);
+
+__webpack_require__(1308);
 
 var _devtoolsSplitter = __webpack_require__(910);
 
 var _devtoolsSplitter2 = _interopRequireDefault(_devtoolsSplitter);
 
 var _ProjectSearch = __webpack_require__(1139);
 
 var _ProjectSearch2 = _interopRequireDefault(_ProjectSearch);
@@ -16087,16 +16078,20 @@ var _WelcomeBox2 = _interopRequireDefaul
 var _Tabs = __webpack_require__(750);
 
 var _Tabs2 = _interopRequireDefault(_Tabs);
 
 var _SymbolModal = __webpack_require__(1170);
 
 var _SymbolModal2 = _interopRequireDefault(_SymbolModal);
 
+var _GotoLineModal = __webpack_require__(1346);
+
+var _GotoLineModal2 = _interopRequireDefault(_GotoLineModal);
+
 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
 
 var shortcuts = new _devtoolsModules.KeyShortcuts({ window });
 
 var appinfo = _devtoolsModules.Services.appinfo;
 
 
 var isMacOS = appinfo.OS === "Darwin";
@@ -16112,36 +16107,44 @@ class App extends _react.Component {
       horizontal: verticalLayoutBreakpoint.matches,
       startPanelSize: 0,
       endPanelSize: 0
     };
 
     this.getChildContext = this.getChildContext.bind(this);
     this.onLayoutChange = this.onLayoutChange.bind(this);
     this.toggleSymbolModal = this.toggleSymbolModal.bind(this);
+    this.toggleGoToLineModal = this.toggleGoToLineModal.bind(this);
     this.renderEditorPane = this.renderEditorPane.bind(this);
     this.renderVerticalLayout = this.renderVerticalLayout.bind(this);
     this.onEscape = this.onEscape.bind(this);
     this.onCommandSlash = this.onCommandSlash.bind(this);
   }
 
   getChildContext() {
     return { shortcuts };
   }
 
   componentDidMount() {
     verticalLayoutBreakpoint.addListener(this.onLayoutChange);
+
     shortcuts.on(L10N.getStr("symbolSearch.search.key2"), this.toggleSymbolModal);
+
+    shortcuts.on(L10N.getStr("gotoLineModal.key"), this.toggleGoToLineModal);
+
     shortcuts.on("Escape", this.onEscape);
     shortcuts.on("Cmd+/", this.onCommandSlash);
   }
 
   componentWillUnmount() {
     verticalLayoutBreakpoint.removeListener(this.onLayoutChange);
     shortcuts.off(L10N.getStr("symbolSearch.search.key2"), this.toggleSymbolModal);
+
+    shortcuts.off(L10N.getStr("gotoLineModal.key"), this.toggleGoToLineModal);
+
     shortcuts.off("Escape", this.onEscape);
   }
 
   onEscape(_, e) {
     var _props = this.props,
         activeSearch = _props.activeSearch,
         closeActiveSearch = _props.closeActiveSearch;
 
@@ -16173,26 +16176,48 @@ class App extends _react.Component {
 
     if (activeSearch == "symbol") {
       return closeActiveSearch();
     }
 
     setActiveSearch("symbol");
   }
 
+  toggleGoToLineModal(_, e) {
+    var _props3 = this.props,
+        selectedSource = _props3.selectedSource,
+        activeSearch = _props3.activeSearch,
+        closeActiveSearch = _props3.closeActiveSearch,
+        setActiveSearch = _props3.setActiveSearch;
+
+
+    e.preventDefault();
+    e.stopPropagation();
+
+    if (!selectedSource) {
+      return;
+    }
+
+    if (activeSearch == "line") {
+      return closeActiveSearch();
+    }
+
+    setActiveSearch("line");
+  }
+
   onLayoutChange() {
     if ((0, _ui.isVisible)()) {
       this.setState({ horizontal: verticalLayoutBreakpoint.matches });
     }
   }
 
   renderEditorPane() {
-    var _props3 = this.props,
-        startPanelCollapsed = _props3.startPanelCollapsed,
-        endPanelCollapsed = _props3.endPanelCollapsed;
+    var _props4 = this.props,
+        startPanelCollapsed = _props4.startPanelCollapsed,
+        endPanelCollapsed = _props4.endPanelCollapsed;
     var _state = this.state,
         horizontal = _state.horizontal,
         endPanelSize = _state.endPanelSize,
         startPanelSize = _state.startPanelSize;
 
 
     return _react2.default.createElement(
       "div",
@@ -16220,19 +16245,19 @@ class App extends _react.Component {
 
   toggleShortcutsModal() {
     this.setState({
       shortcutsModalEnabled: !this.state.shortcutsModalEnabled
     });
   }
 
   renderHorizontalLayout() {
-    var _props4 = this.props,
-        startPanelCollapsed = _props4.startPanelCollapsed,
-        endPanelCollapsed = _props4.endPanelCollapsed;
+    var _props5 = this.props,
+        startPanelCollapsed = _props5.startPanelCollapsed,
+        endPanelCollapsed = _props5.endPanelCollapsed;
     var horizontal = this.state.horizontal;
 
 
     var overflowX = endPanelCollapsed ? "hidden" : "auto";
 
     return _react2.default.createElement(_devtoolsSplitter2.default, {
       style: { width: "100vw" },
       initialSize: "250px",
@@ -16257,19 +16282,19 @@ class App extends _react.Component {
         }),
         endPanelCollapsed: endPanelCollapsed,
         vert: horizontal
       })
     });
   }
 
   renderVerticalLayout() {
-    var _props5 = this.props,
-        startPanelCollapsed = _props5.startPanelCollapsed,
-        endPanelCollapsed = _props5.endPanelCollapsed;
+    var _props6 = this.props,
+        startPanelCollapsed = _props6.startPanelCollapsed,
+        endPanelCollapsed = _props6.endPanelCollapsed;
     var horizontal = this.state.horizontal;
 
 
     return _react2.default.createElement(_devtoolsSplitter2.default, {
       style: { width: "100vw" },
       initialSize: "300px",
       minSize: 30,
       maxSize: "99%",
@@ -16286,32 +16311,49 @@ class App extends _react.Component {
         endPanel: this.renderEditorPane()
       }),
       endPanel: _react2.default.createElement(_SecondaryPanes2.default, { horizontal: horizontal }),
       endPanelCollapsed: endPanelCollapsed
     });
   }
 
   renderSymbolModal() {
-    var _props6 = this.props,
-        selectSource = _props6.selectSource,
-        selectedSource = _props6.selectedSource,
-        activeSearch = _props6.activeSearch;
+    var _props7 = this.props,
+        selectSource = _props7.selectSource,
+        selectedSource = _props7.selectedSource,
+        activeSearch = _props7.activeSearch;
 
 
     if (activeSearch !== "symbol") {
       return;
     }
 
     return _react2.default.createElement(_SymbolModal2.default, {
       selectSource: selectSource,
       selectedSource: selectedSource
     });
   }
 
+  renderGotoLineModal() {
+    var _props8 = this.props,
+        selectSource = _props8.selectSource,
+        selectedSource = _props8.selectedSource,
+        activeSearch = _props8.activeSearch;
+
+
+    if (activeSearch !== "line") {
+      return;
+    }
+
+    return _react2.default.createElement(_GotoLineModal2.default, {
+      selectSource: selectSource,
+      selectedSource: selectedSource
+    });
+  }
+
   renderShortcutsModal() {
     var additionalClass = isMacOS ? "mac" : "";
 
     if (!_prefs.features.shortcuts) {
       return;
     }
 
     return _react2.default.createElement(_ShortcutsModal.ShortcutsModal, {
@@ -16322,16 +16364,17 @@ class App extends _react.Component {
   }
 
   render() {
     return _react2.default.createElement(
       "div",
       { className: "debugger" },
       this.state.horizontal ? this.renderHorizontalLayout() : this.renderVerticalLayout(),
       this.renderSymbolModal(),
+      this.renderGotoLineModal(),
       this.renderShortcutsModal()
     );
   }
 }
 
 App.childContextTypes = { shortcuts: _propTypes2.default.object };
 
 exports.default = (0, _reactRedux.connect)(state => ({
@@ -20262,17 +20305,17 @@ var _react2 = _interopRequireDefault(_re
 var _classnames = __webpack_require__(175);
 
 var _classnames2 = _interopRequireDefault(_classnames);
 
 var _Transition = __webpack_require__(333);
 
 var _Transition2 = _interopRequireDefault(_Transition);
 
-__webpack_require__(1226);
+__webpack_require__(1303);
 
 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
 
 class Modal extends _react.Component {
   constructor() {
     var _temp;
 
     return _temp = super(...arguments), this.onClick = e => {
@@ -21727,17 +21770,17 @@ var _react2 = _interopRequireDefault(_re
 var _fuzzaldrinPlus = __webpack_require__(161);
 
 var _classnames = __webpack_require__(175);
 
 var _classnames2 = _interopRequireDefault(_classnames);
 
 var _resultList = __webpack_require__(343);
 
-__webpack_require__(1240);
+__webpack_require__(1315);
 
 var _SearchInput = __webpack_require__(377);
 
 var _SearchInput2 = _interopRequireDefault(_SearchInput);
 
 var _ResultList = __webpack_require__(383);
 
 var _ResultList2 = _interopRequireDefault(_ResultList);
@@ -21959,17 +22002,17 @@ exports.handleKeyDown = handleKeyDown;
 Object.defineProperty(exports, "__esModule", {
   value: true
 });
 
 var _Svg = __webpack_require__(345);
 
 var _Svg2 = _interopRequireDefault(_Svg);
 
-__webpack_require__(1234);
+__webpack_require__(1310);
 
 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
 
 /**
  * This file maps the SVG React Components in the assets/images directory.
  */
 
 exports.default = _Svg2.default;
@@ -22025,18 +22068,18 @@ var svg = {
   stepIn: __webpack_require__(365),
   stepOut: __webpack_require__(366),
   stepOver: __webpack_require__(367),
   subSettings: __webpack_require__(368),
   toggleBreakpoints: __webpack_require__(369),
   togglePanes: __webpack_require__(370),
   "whole-word-match": __webpack_require__(371),
   worker: __webpack_require__(372),
-  "sad-face": __webpack_require__(373),
-  refresh: __webpack_require__(374),
+  "sad-face": __webpack_require__(1347),
+  refresh: __webpack_require__(1348),
   webpack: __webpack_require__(1001),
   node: __webpack_require__(1002),
   express: __webpack_require__(1003),
   pug: __webpack_require__(1004),
   extjs: __webpack_require__(1043),
   showSources: __webpack_require__(1044),
   showOutline: __webpack_require__(1045),
   shortcut: __webpack_require__(1183)
@@ -22382,28 +22425,18 @@ module.exports = "<svg xmlns=\"http://ww
 
 /***/ }),
 /* 372 */
 /***/ (function(module, exports) {
 
 module.exports = "<!-- This Source Code Form is subject to the terms of the Mozilla Public - License, v. 2.0. If a copy of the MPL was not distributed with this - file, You can obtain one at http://mozilla.org/MPL/2.0/. --><svg viewBox=\"0 0 16 16\" xmlns=\"http://www.w3.org/2000/svg\"><path fill-rule=\"evenodd\" d=\"M8.5 8.793L5.854 6.146l-.04-.035L7.5 4.426c.2-.2.3-.4.3-.6 0-.2-.1-.4-.2-.6l-1-1c-.4-.3-.9-.3-1.2 0l-4.1 4.1c-.2.2-.3.4-.3.6 0 .2.1.4.2.6l1 1c.3.3.9.3 1.2 0l1.71-1.71.036.04L7.793 9.5l-3.647 3.646c-.195.196-.195.512 0 .708.196.195.512.195.708 0L8.5 10.207l3.646 3.647c.196.195.512.195.708 0 .195-.196.195-.512 0-.708L9.207 9.5l2.565-2.565L13.3 8.5c.1.1 2.3 1.1 2.7.7.4-.4-.3-2.7-.5-2.9l-1.1-1.1c.1-.1.2-.4.2-.6 0-.2-.1-.4-.2-.6l-.4-.4c-.3-.3-.8-.3-1.1 0l-1.5-1.4c-.2-.2-.3-.2-.5-.2s-.3.1-.5.2L9.2 3.4c-.2.1-.2.2-.2.4s.1.4.2.5l1.874 1.92L8.5 8.792z\"></path></svg>"
 
 /***/ }),
-/* 373 */
-/***/ (function(module, exports) {
-
-module.exports = "<!-- This Source Code Form is subject to the terms of the Mozilla Public - License, v. 2.0. If a copy of the MPL was not distributed with this - file, You can obtain one at http://mozilla.org/MPL/2.0/. --><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 16 16\" fill=\"#D92215\"><path d=\"M8 14.5c-3.6 0-6.5-2.9-6.5-6.5S4.4 1.5 8 1.5s6.5 2.9 6.5 6.5-2.9 6.5-6.5 6.5zm0-12C5 2.5 2.5 5 2.5 8S5 13.5 8 13.5 13.5 11 13.5 8 11 2.5 8 2.5z\"></path><circle cx=\"5\" cy=\"6\" r=\"1\" transform=\"translate(1 1)\"></circle><circle cx=\"9\" cy=\"6\" r=\"1\" transform=\"translate(1 1)\"></circle><path d=\"M5.5 11c-.1 0-.2 0-.3-.1-.2-.1-.3-.4-.1-.7C6 9 7 8.5 8.1 8.5c1.7.1 2.8 1.7 2.8 1.8.2.2.1.5-.1.7-.2.1-.6 0-.7-.2 0 0-.9-1.3-2-1.3-.7 0-1.4.4-2.1 1.3-.2.2-.4.2-.5.2z\"></path></svg>"
-
-/***/ }),
-/* 374 */
-/***/ (function(module, exports) {
-
-module.exports = "<!-- This Source Code Form is subject to the terms of the Mozilla Public - License, v. 2.0. If a copy of the MPL was not distributed with this - file, You can obtain one at http://mozilla.org/MPL/2.0/. --><svg viewBox=\"0 0 16 16\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M13.917 7C13.44 4.162 10.973 2 8 2 4.686 2 2 4.686 2 8s2.686 6 6 6c2.22 0 4.16-1.207 5.197-3H12c-.912 1.214-2.364 2-4 2-2.76 0-5-2.24-5-5s2.24-5 5-5c2.42 0 4.437 1.718 4.9 4h1.017z\"></path><path d=\"M14 1L8 7h6V1zm-1 1L9 6h4V2z\" fill-rule=\"evenodd\"></path></svg>"
-
-/***/ }),
+/* 373 */,
+/* 374 */,
 /* 375 */,
 /* 376 */,
 /* 377 */
 /***/ (function(module, exports, __webpack_require__) {
 
 "use strict";
 
 
@@ -22424,17 +22457,17 @@ var _Svg2 = _interopRequireDefault(_Svg)
 var _classnames = __webpack_require__(175);
 
 var _classnames2 = _interopRequireDefault(_classnames);
 
 var _Close = __webpack_require__(378);
 
 var _Close2 = _interopRequireDefault(_Close);
 
-__webpack_require__(1237);
+__webpack_require__(1313);
 
 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
 
 var arrowBtn = (onClick, type, className, tooltip) => {
   var props = {
     onClick,
     type,
     className,
@@ -22568,17 +22601,17 @@ Object.defineProperty(exports, "__esModu
 var _react = __webpack_require__(0);
 
 var _react2 = _interopRequireDefault(_react);
 
 var _Svg = __webpack_require__(344);
 
 var _Svg2 = _interopRequireDefault(_Svg);
 
-__webpack_require__(1236);
+__webpack_require__(1312);
 
 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
 
 function CloseButton(_ref) {
   var handleClick = _ref.handleClick,
       buttonClass = _ref.buttonClass,
       tooltip = _ref.tooltip;
 
@@ -22612,17 +22645,17 @@ Object.defineProperty(exports, "__esModu
 var _react = __webpack_require__(0);
 
 var _react2 = _interopRequireDefault(_react);
 
 var _classnames = __webpack_require__(175);
 
 var _classnames2 = _interopRequireDefault(_classnames);
 
-__webpack_require__(1241);
+__webpack_require__(1316);
 
 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
 
 class ResultList extends _react.Component {
 
   constructor(props) {
     super(props);
     this.renderListItem = this.renderListItem.bind(this);
@@ -22769,36 +22802,55 @@ Object.defineProperty(exports, "__esModu
 });
 
 var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
 
 var _react = __webpack_require__(0);
 
 var _react2 = _interopRequireDefault(_react);
 
-__webpack_require__(1235);
+__webpack_require__(1311);
 
 var _devtoolsComponents = __webpack_require__(1007);
 
 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
 
 var Tree = (0, _react.createFactory)(_devtoolsComponents.Tree);
 
 class ManagedTree extends _react.Component {
 
   constructor(props) {
     super();
 
-    this.setExpanded = (item, isExpanded) => {
+    this.setExpanded = (item, isExpanded, shouldIncludeChildren) => {
+      var expandItem = i => {
+        var path = this.props.getPath(i);
+        if (isExpanded) {
+          expanded.add(path);
+        } else {
+          expanded.delete(path);
+        }
+      };
       var expanded = this.state.expanded;
-      var itemPath = this.props.getPath(item);
-      if (isExpanded) {
-        expanded.add(itemPath);
-      } else {
-        expanded.delete(itemPath);
+      expandItem(item);
+
+      if (shouldIncludeChildren) {
+        var parents = [item];
+        while (parents.length) {
+          var children = [];
+          for (var parent of parents) {
+            if (parent.contents && parent.contents.length) {
+              for (var child of parent.contents) {
+                expandItem(child);
+                children.push(child);
+              }
+            }
+          }
+          parents = children;
+        }
       }
       this.setState({ expanded });
 
       if (isExpanded && this.props.onExpand) {
         this.props.onExpand(item, expanded);
       } else if (!isExpanded && this.props.onCollapse) {
         this.props.onCollapse(item, expanded);
       }
@@ -22864,18 +22916,18 @@ class ManagedTree extends _react.Compone
         expanded = _state.expanded,
         focusedItem = _state.focusedItem;
 
 
     var overrides = {
       isExpanded: item => expanded.has(this.props.getPath(item)),
       focused: focusedItem,
       getKey: this.props.getPath,
-      onExpand: item => this.setExpanded(item, true),
-      onCollapse: item => this.setExpanded(item, false),
+      onExpand: item => this.setExpanded(item, true, false),
+      onCollapse: item => this.setExpanded(item, false, false),
       onFocus: this.focusItem,
       renderItem: function () {
         var _props;
 
         for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
           args[_key] = arguments[_key];
         }
 
@@ -23022,19 +23074,19 @@ var _EditorMenu = __webpack_require__(65
 var _EditorMenu2 = _interopRequireDefault(_EditorMenu);
 
 var _ConditionalPanel = __webpack_require__(711);
 
 var _ConditionalPanel2 = _interopRequireDefault(_ConditionalPanel);
 
 var _editor = __webpack_require__(257);
 
-__webpack_require__(1257);
-
-__webpack_require__(1258);
+__webpack_require__(1332);
+
+__webpack_require__(1333);
 
 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
 
 var cssVars = {
   searchbarHeight: "var(--editor-searchbar-height)",
   secondSearchbarHeight: "var(--editor-second-searchbar-height)",
   footerHeight: "var(--editor-footer-height)"
 };
@@ -23602,17 +23654,17 @@ var _devtoolsConfig = __webpack_require_
 var _source = __webpack_require__(233);
 
 var _editor = __webpack_require__(257);
 
 var _PaneToggle = __webpack_require__(428);
 
 var _PaneToggle2 = _interopRequireDefault(_PaneToggle);
 
-__webpack_require__(1248);
+__webpack_require__(1322);
 
 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
 
 class SourceFooter extends _react.PureComponent {
 
   prettyPrintButton() {
     var _props = this.props,
         selectedSource = _props.selectedSource,
@@ -23781,17 +23833,17 @@ var _react2 = _interopRequireDefault(_re
 var _classnames = __webpack_require__(175);
 
 var _classnames2 = _interopRequireDefault(_classnames);
 
 var _Svg = __webpack_require__(344);
 
 var _Svg2 = _interopRequireDefault(_Svg);
 
-__webpack_require__(1247);
+__webpack_require__(1321);
 
 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
 
 class PaneToggleButton extends _react.Component {
 
   shouldComponentUpdate(nextProps) {
     var _props = this.props,
         collapsed = _props.collapsed,
@@ -23879,17 +23931,17 @@ var _classnames2 = _interopRequireDefaul
 var _lodash = __webpack_require__(2);
 
 var _devtoolsSourceEditor = __webpack_require__(994);
 
 var _SearchInput = __webpack_require__(377);
 
 var _SearchInput2 = _interopRequireDefault(_SearchInput);
 
-__webpack_require__(1249);
+__webpack_require__(1323);
 
 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
 
 function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; }
 
 function getShortcuts() {
   var searchAgainKey = L10N.getStr("sourceSearch.search.again.key2");
   var searchAgainPrevKey = L10N.getStr("sourceSearch.search.againPrev.key2");
@@ -24925,17 +24977,17 @@ var _reactDom2 = _interopRequireDefault(
 var _classnames = __webpack_require__(175);
 
 var _classnames2 = _interopRequireDefault(_classnames);
 
 var _BracketArrow = __webpack_require__(1029);
 
 var _BracketArrow2 = _interopRequireDefault(_BracketArrow);
 
-__webpack_require__(1253);
+__webpack_require__(1327);
 
 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
 
 class Popover extends _react.Component {
 
   constructor() {
     super();
     this.onMouseLeave = this.onMouseLeave.bind(this);
@@ -25138,17 +25190,17 @@ var _reactDom2 = _interopRequireDefault(
 var _redux = __webpack_require__(3);
 
 var _reactRedux = __webpack_require__(1189);
 
 var _Close = __webpack_require__(378);
 
 var _Close2 = _interopRequireDefault(_Close);
 
-__webpack_require__(1246);
+__webpack_require__(1331);
 
 var _editor = __webpack_require__(257);
 
 var _actions = __webpack_require__(244);
 
 var _actions2 = _interopRequireDefault(_actions);
 
 var _selectors = __webpack_require__(242);
@@ -25555,17 +25607,17 @@ var _UtilsBar2 = _interopRequireDefault(
 var _ChromeScopes = __webpack_require__(728);
 
 var _ChromeScopes2 = _interopRequireDefault(_ChromeScopes);
 
 var _Scopes2 = __webpack_require__(731);
 
 var _Scopes3 = _interopRequireDefault(_Scopes2);
 
-__webpack_require__(1267);
+__webpack_require__(1342);
 
 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
 
 function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }
 
 var Scopes = (0, _devtoolsConfig.isEnabled)("chromeScopes") ? _ChromeScopes2.default : _Scopes3.default;
 
 function debugBtn(onClick, type, className, tooltip) {
@@ -25797,17 +25849,17 @@ var _selectors = __webpack_require__(242
 var _expressions = __webpack_require__(1177);
 
 var _Close = __webpack_require__(378);
 
 var _Close2 = _interopRequireDefault(_Close);
 
 var _devtoolsReps = __webpack_require__(924);
 
-__webpack_require__(1260);
+__webpack_require__(1335);
 
 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
 
 class Expressions extends _react.PureComponent {
 
   constructor() {
     super(...arguments);
 
@@ -26042,17 +26094,17 @@ var _utils = __webpack_require__(234);
 var _source = __webpack_require__(233);
 
 var _devtoolsLaunchpad = __webpack_require__(131);
 
 var _Close = __webpack_require__(378);
 
 var _Close2 = _interopRequireDefault(_Close);
 
-__webpack_require__(1259);
+__webpack_require__(1334);
 
 var _lodash = __webpack_require__(2);
 
 function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
 
 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
 
 function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }
@@ -26419,17 +26471,17 @@ var _selectors = __webpack_require__(242
 var _Svg = __webpack_require__(344);
 
 var _Svg2 = _interopRequireDefault(_Svg);
 
 var _ManagedTree = __webpack_require__(419);
 
 var _ManagedTree2 = _interopRequireDefault(_ManagedTree);
 
-__webpack_require__(1216);
+__webpack_require__(1296);
 
 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
 
 // check to see if its an object with propertie
 function nodeHasProperties(item) {
   return !nodeHasChildren(item) && item.contents.value.type === "object";
 }
 
@@ -26656,17 +26708,17 @@ var _actions = __webpack_require__(244);
 var _actions2 = _interopRequireDefault(_actions);
 
 var _selectors = __webpack_require__(242);
 
 var _scopes = __webpack_require__(732);
 
 var _devtoolsReps = __webpack_require__(924);
 
-__webpack_require__(1216);
+__webpack_require__(1296);
 
 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
 
 class Scopes extends _react.PureComponent {
 
   constructor(props) {
     var pauseInfo = props.pauseInfo,
         selectedFrame = props.selectedFrame,
@@ -26953,17 +27005,17 @@ var _actions = __webpack_require__(244);
 var _actions2 = _interopRequireDefault(_actions);
 
 var _selectors = __webpack_require__(242);
 
 var _Close = __webpack_require__(378);
 
 var _Close2 = _interopRequireDefault(_Close);
 
-__webpack_require__(1264);
+__webpack_require__(1339);
 
 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
 
 class EventListeners extends _react.Component {
 
   constructor() {
     super(...arguments);
 
@@ -27067,17 +27119,17 @@ Object.defineProperty(exports, "__esModu
 var _react = __webpack_require__(0);
 
 var _react2 = _interopRequireDefault(_react);
 
 var _Svg = __webpack_require__(344);
 
 var _Svg2 = _interopRequireDefault(_Svg);
 
-__webpack_require__(1266);
+__webpack_require__(1341);
 
 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
 
 function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }
 
 class Accordion extends _react.Component {
 
   constructor(props) {
@@ -27200,17 +27252,17 @@ var _Svg = __webpack_require__(344);
 var _Svg2 = _interopRequireDefault(_Svg);
 
 var _text = __webpack_require__(389);
 
 var _actions = __webpack_require__(244);
 
 var _actions2 = _interopRequireDefault(_actions);
 
-__webpack_require__(1215);
+__webpack_require__(1295);
 
 var _devtoolsModules = __webpack_require__(830);
 
 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
 
 var appinfo = _devtoolsModules.Services.appinfo;
 
 
@@ -27417,17 +27469,17 @@ var _actions2 = _interopRequireDefault(_
 var _selectors = __webpack_require__(242);
 
 var _text = __webpack_require__(389);
 
 var _PaneToggle = __webpack_require__(428);
 
 var _PaneToggle2 = _interopRequireDefault(_PaneToggle);
 
-__webpack_require__(1268);
+__webpack_require__(1343);
 
 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
 
 class WelcomeBox extends _react.Component {
 
   renderToggleButton() {
     var _props = this.props,
         horizontal = _props.horizontal,
@@ -27576,17 +27628,17 @@ var _Svg = __webpack_require__(344);
 var _Svg2 = _interopRequireDefault(_Svg);
 
 var _devtoolsLaunchpad = __webpack_require__(131);
 
 var _lodash = __webpack_require__(2);
 
 var _text = __webpack_require__(389);
 
-__webpack_require__(1269);
+__webpack_require__(1344);
 
 var _PaneToggle = __webpack_require__(428);
 
 var _PaneToggle2 = _interopRequireDefault(_PaneToggle);
 
 var _Dropdown = __webpack_require__(751);
 
 var _Dropdown2 = _interopRequireDefault(_Dropdown);
@@ -28047,17 +28099,17 @@ exports.default = (0, _reactRedux.connec
 Object.defineProperty(exports, "__esModule", {
   value: true
 });
 
 var _react = __webpack_require__(0);
 
 var _react2 = _interopRequireDefault(_react);
 
-__webpack_require__(1270);
+__webpack_require__(1345);
 
 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
 
 class Dropdown extends _react.Component {
 
   constructor(props) {
     super(props);
     this.state = {
@@ -28334,17 +28386,17 @@ Object.defineProperty(exports, "__esModu
 var _react = __webpack_require__(0);
 
 var _react2 = _interopRequireDefault(_react);
 
 var _lodash = __webpack_require__(2);
 
 var _frame = __webpack_require__(1014);
 
-__webpack_require__(1245);
+__webpack_require__(1320);
 
 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
 
 function getFunctionName(func) {
   var name = func.userDisplayName || func.displayName || func.name;
   return (0, _frame.simplifyDisplayName)(name);
 }
 
@@ -28686,17 +28738,17 @@ var _Popover = __webpack_require__(698);
 var _Popover2 = _interopRequireDefault(_Popover);
 
 var _PreviewFunction = __webpack_require__(798);
 
 var _PreviewFunction2 = _interopRequireDefault(_PreviewFunction);
 
 var _editor = __webpack_require__(257);
 
-__webpack_require__(1254);
+__webpack_require__(1328);
 
 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
 
 var Rep = _devtoolsReps2.default.REPS.Rep,
     MODE = _devtoolsReps2.default.MODE,
     ObjectInspectorUtils = _devtoolsReps2.default.ObjectInspectorUtils;
 var ObjectInspector = _devtoolsReps2.default.ObjectInspector;
 var getChildren = ObjectInspectorUtils.getChildren;
@@ -29087,22 +29139,17 @@ module.exports = {
 /* 847 */,
 /* 848 */,
 /* 849 */,
 /* 850 */,
 /* 851 */,
 /* 852 */,
 /* 853 */,
 /* 854 */,
-/* 855 */
-/***/ (function(module, exports) {
-
-module.exports = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAF4AAABqCAMAAAAC5xbnAAAABGdBTUEAALGPC/xhBQAAAAFzUkdCAK7OHOkAAAFZaVRYdFhNTDpjb20uYWRvYmUueG1wAAAAAAA8eDp4bXBtZXRhIHhtbG5zOng9ImFkb2JlOm5zOm1ldGEvIiB4OnhtcHRrPSJYTVAgQ29yZSA1LjQuMCI+CiAgIDxyZGY6UkRGIHhtbG5zOnJkZj0iaHR0cDovL3d3dy53My5vcmcvMTk5OS8wMi8yMi1yZGYtc3ludGF4LW5zIyI+CiAgICAgIDxyZGY6RGVzY3JpcHRpb24gcmRmOmFib3V0PSIiCiAgICAgICAgICAgIHhtbG5zOnRpZmY9Imh0dHA6Ly9ucy5hZG9iZS5jb20vdGlmZi8xLjAvIj4KICAgICAgICAgPHRpZmY6T3JpZW50YXRpb24+MTwvdGlmZjpPcmllbnRhdGlvbj4KICAgICAgPC9yZGY6RGVzY3JpcHRpb24+CiAgIDwvcmRmOlJERj4KPC94OnhtcG1ldGE+CkzCJ1kAAAMAUExURUxpcf/fQOF4Wf6qob2GSbyGTP61q++hVlpCNO+ATLuESaZzPYdWLZ1uN/KOQywvJ/OGDfeTGWRSMlpFNvqrQ/yNkPipLfeTGviRGyobJAYCC5BgL/y2MKJrRg0gKH5ULfSTIWhnYyIeJv5/g7K1tfiSGviWIIZgPP+jn6KnqJxqNvmWH/qdTJNkM/6GjPmdKX5JIKiIafeVHTcuLK9uHvTn0/iUH5NiKQUbM/eTH0ExL/6hmv/TStTCqvidK/6Oi/uTkOnZv/mgNLaHbZppFu6ooPeMGYJVJOzbu5pqOap2RY+WnZaOgv+cmahkY/LjzvaEE+vew/2blzs+Ov6enQohIsVvb/+QkP6Bg4+YntB4de7Ru7yfg6KEaf+movj07s7Husx9atqYPJVKKLqESf/47v22GuJOM/3LLf/////ZY//37fyzGP3y4v2rFv3JLP3z5fuiEt9HM/3CKAAAAN1BL//+9f7NLtk7KP726NY0ILB4P/7XYvukH95HLf/88v65Gvy6J/7IKPPizLZ7QPqPEPru3N1AJ7+ITP+vprqAQ+p5IPiZGbV/Rfz8/PyzJv+lmP7VOfitIvqzT/zozeTMtf/RLvycCcSKTP29Hv/ocf/Btv3LOOdpHQQaI/7RY+JcJaltNP66r/3AM6OEMPCMH+nq6/Lz9JpiLzk3M/nYxE40H7WTMcgvHk9AMsLEwyQsL/u8ANrEqurWwJp2Jtrc3WRNR//76fzPsmJHI+FZHvfo1+WiHf3BV/p4dHVdMwABKfDALbV6Kt9PJ91+YHY/L6OVhJksJyIdGcUjB4VrMLd9OMqiL7EqIEJAP/3LXtu5maAFBP7OQ/yWj5GXl7w7K8GLHH1RLNyuLXklJ83Q0WYzLs2THIJJC/+PeXp4cIoABOe4LTUlJ//hbMWXYISKivqqA8udeemXhXtaHOiHc9YLAM1AKI+Ec7ideFVgYNs0BrgSAJh3YcRwII1ZGMCsj2QCAteBEXqDgviWNfW4esd1S8e4ofbDnNVeSrxWUew/xBkAAABkdFJOUwD+EP7//v4CAwX8/mb9HhH/MP3+/TT9TdYm/oP90bA4bPtYefztff7J+buL991SyUn+Y9v62T+cfp3S9P5co9TrkLj++vmqnHCp90X+nf3EvKx27ZH14bSWoqznwX6h/sly7fPC0KykAAAQBUlEQVRo3tyYe0xTWR7Hb+nwKKs4IK9UnAED+CIiLMvE9ZH1Oc64Pnc0O7O7/0nDo8/0BtKUptQ+VgzSUqCVR0oKXWhpAx0oQsOrGDWkQ8AVFggBFBWVSZTERxzHcXZ/59wWWakOGdl/9isgve39nO/9nd/5/c6BIP6/Fcj4X4EDA+Eb/4+00nTkPJAICcW/en6sJB2FJTQmJgp+i00lVtQ/wLYmJ0bFRpfQEnYk7tPx0vGzrNyEhtbR1BKuurpEreaqS0qi4SGIFZpmwIRG19FiWGxZdYlMxpJVVxcpD6UTKxIhYDASi7iyEhmFxz8lXIHyUOgKzDDQ05PrhDKMV9ct4LkCQULsB/Ph9tTIEhpNpi6pk7FldTRZhQfPZXMlWz+QD95jY2ggoZomZHO16jqtlqsVYjyL9cF8BhGlRvQSobYuMjy8lFJ4JODZLDbwUz8EzyBCIhE8kyeMLO0eqqnJR6qp6Q4XAB7xE0KAH8hgMH5d4PdA3Et4vDx1aU12dr5H2fmlAqADnsXdQfzq9QWrKQbRMzMBn79I2d0YD3x2AqSn3+5TET5X4/tGDoIH3lqC6bw82X/h73rwMIAkkTj8l4Ba+qkl3hjvK334OiOZRuN58DWL8JVDXvcsffJJToAmoDZg2+IigStSYOg7Fx5c/XTd51siaTqgv42/Wzkk8eDVyiRR7TCdHlC1aQFFtYOQ2H3h4e9I3EAi6JurPVevqkuw+UweK3wBn323ksKzIfQS/UvNMF2D8H7YPlVJ/aL2JHXDHaVRvgoffOLP06Akdh4Puxe+wQO8srJGgtKexRYIJMokOoVn4BRFt4cmJpcO1UCCZQ/t8Z0yERrNTo1m+j4PWT8nRPhsr3WEj2QVQFYK9Hrlxy81dE1hQNVRz2yGpO4LR8bxx2uSQnzYZxDbAgI0GA8SgioQ3sOuvAt4rqRIiVUE/MKAgMJtuKVF7YCgLCyR7PzuWJ/4CHpt4cOHSXqJRKvVqtVqbThatDVDQ90gKAuIXQRvqiH4SRpqZqmg5NekxN3btWvXTdCu/Jp9PiYXSvymqoOXX9TdrNMWUZJERkokEgEWlLaYOpCMfV9f9PTL/RvXHoS8REEZGtq1yzbY1NQ3PnMOKfNmeKjv6NQetL6IjLlJo1XfrPaKl5kH0unOfYt0X69/+Y9nrvl5O/PBV4zkGLBbzTvXZxkYcJtclnH4JEQ2JtF3UztaldJvvfbiPgJVfEsJHMeAIsNLf/zx9euOxk5V24h98PJpw3oiNaY6D+zydLawTN2AxdZks5n6YARhtJ+P1A8k/DZV7Tcw48obGzs6Hr7uQLqRlvb06VPz1HV+hrQ4Kwu+srIaNpPMy2dCiER1Jg+nWa9jfMbkmAmzNbl6+/ryzhVF+VpZDOAXriVnGwBRb59ApKwJst8sNjrJWQxui6tHIzSTd85AQQstEiK+LtPhOu0IGze5HW6bZSDMMS7Y4TM6ML1Hn5A/FAOimYzH+M3kmOKiwsycBy51FeN/j3N7nwxqx8yArs80MGC3rbWFjdvcpqbT9iLcEnzuP1aRcQ0Y34x4DXGk+YJCYbSSE+hlGzmCxownNxBowcZKhJk6k3t8QKfrC3OZTO4ZGMI9OaoVpPreETGINX9itgG+fnMDZddqVIjF4jEUHfg324zcz5J/I4JQX0tg5fF6bb0mGzzBTN9a+1q3ze4arWBxT7yrrh1+To7gOCPVz5PXxK9eKRTmfngar9qYU+sDcZHcIxGOh7mbIGdMjj7duLt3IOzAZBcLdxyfdc3vd3IrM76+obi4oaF+4hZ559nVnp6eV0Yr83IzXIXcaWi7Rf5GvB1uh6ZfVDBqt/eGmUx2l6lvJk83bjA4cN1L9I3fm6V60M+c/2F29lbcIEnap4wYL3522kAOxs2OjIzMzpNjwZe2UGaiuXOuXnvvQNO422RymYQFXQfmtAXQ76MZS6MDdUeVm9N6z0lSsjqnzGKx8WcjTO6U9Y7nKukU+5//8lM8uVslcw63axwnfa/bNTnZVUE1zKL0JfahoRwvzskQNd54nPLkScqTKbPRKEYTi2Q0ms0bx65Zr21crfjobPD5dajUQ+pztc8cWsuAyW1yTjpHnaOjk97txNv2YV6l0pycDKmqDCRvfZCWRqEVlIzmMeuY+IK/v//Z4Evr1xBBcH8yt0DL7rIarKNOg8uRZp1zjVI9Lfrt1EfzCuYz4Isjb5XDCC33FIoLFxUKsdG82jzmtPYbmAeuXElL+84/GEUnCKc+G5rM5NykY+7ZXJfT5ewqADirgpuwFH84F7FBIlX54+vPf2q5sd/8bAo0t9pJMg12i+HxjfLW8hv3rpz1P7sKRyckAbXIgoKCtEmHY9RlmKyAVyzY6u55Kzhe86AcPoff+Ueyv99iSXn8+Dkg5U9Ii2WQvCUv44hEfFXLd8GX1lEN+pAAB4PFKhh1OA84RyvYbDgIRCf6LTG/my+l8Bl8DkfEeURa7OTjMg6H097efp0ctNj7W8rk8JKTkVsefOkLXKOIKKV3e1XQNdplvcLVKxN2RDF8TOze3IyMBbyqvdViHyQfcdo5ZRw+5zoJ5h/J5Sp4iyPKyG25soXA0fGL1gu4XgmevlCeiA0hfB6Sjhd78SLkUQSODU1ywKva2x/+s8lwx2Oen5Mj7aTco9RXCjzSK5XRW0MXNj5L8ibXExsUfMC3kBbDvzra28vK2jume3puPyrzms+Rqu595jn6pn+sx2wIyqEoP7zTDPRdbhbwlP3Wy8x/90x3lEHv0tALNT3lco95jF+HowvxOaHHex8qKEGMd+0wg46/wUP0+Sr5rdtQb6Y1AYWwqYFtTaPXPOA7L26HvMeFJFaJgpJO/Y3gPdvvk960R+EBfNlPP08P02sDKNFr5Z0eOuAbD6zB+CAi6JOxNE9Q3n8u2d0ufWMfwqNqHB4upESn0wsbVRwvPUfa8jllPYjYMGjYQPzyHwQWLauF8Hc2VtUiVXU0NnZyvN7BPH//dk9FXPPbwU+I5ZyGFq8rD58v4nNUWBw+n5pVCp/xV5w3EQxiQxNzAzULv6y9uYv5OD35lHDKiLxv5PIjUKhDdh6N+AP9m2WfCoNOSqUZix8AY7H4b+Bgfu8RtBMJKaw9M4wOEYHLPBYSezszUMl/8wQibF60cA33g+b45t2QNat2Hjw2XPjVMo/p8KEjX8fL+ainLBrhzVBI0lyRfGKieGL9Z1+sN35/7Bi96uDy3EPqfB3fVh+f0sqBEGHYIix+JZVKOY0P4toaiidSLp0//5HxzrHhnaeWeTw/srkNth8jt//+fXnnfzq1vpC2rjAe9F4bc80MhhZCpqIWnDJLhw8V+2BhD4Wtb13pnvZ0axzahN6QeU0w/ol6r0muFldbRSK2I7F/Fh2KsqogGmOUzGGpobMOdFKmqN10o66Ubuw79yaptrGc5PeQnHvP+X7fd77z7zvnnpq6iApJRx1CTcv9f2d2t/cLPG0jswSsiQ/XN3uSk3DOqI7JPj/paWvzjIzOm7Z3P371o62lRuQET4H/r47bOhdffXtLtWtm5tVP2zyzdppX/tCb+dUXSXieKYAoqd9TsMZYGZ/qlsoxs7nY2Tk8PGwDDP31n297W/W70+0yWZm1l/39BTQhPOwt1uA5Ri7LvjAoGc/omL4T39W6tre3d3e5efXwuK3lwtqu2WRyfNiud/oYHbs/+PXgJ/a7vXO5YriAwa4pCs4+7fcsgfE6k8NYXeVgdDrGxDFrS5XfjKh3dAx6bSjXu0w63d6fnpFZYaA3S4Y1YGFAFXYR5NLI4IMdE/C4DQaRRsT+YOXLRyjB9HVUdOvdVkitLXlOrs7NYU4HctlpC6Gwf1qQs2ey6hhfbYXB2ceI5IzOO7oakBSZ3GD+tT7Q61WfLPh5DtN4sF5LkDTN5yxzyHhXA+yPfEzYet3CfjhhcrVXG/UOoGcWLubMzWkw5zK5TAuBEU892OGsopHVRuSDMEL+SMpXa6joRvViTP5L61m4M6XkHDojYEWOtQKJ0c2aIgj5GcbEILBu2Kx1IPN1oXuXcI1Hc0Yh35W/bDazJisHLQj0LkcEf/v7wrA6GlAWC6rZALbxYsdUCgMhl8vhdjtrgcPQADCKaJx4cqK9o70DQcyqdTscrr6d4vR4+LMv3u5oB0bxNKdC3OoDIHXzl8mpmxWRJ/Gox9jQ3l57uyQu89VTYXHEAGg0RqyfnKo2iK8MYo6ovaJxIh7zZVk/3ZTEgbYbUF9eHglNn/zWaKg4BIOxobzqbi5+19FkgPFQ7W4IzlEw+gZ695OJ+vLublQRBHSShILu+l9xhxV0nZLvq43l+mvOZpUKGs7lGovCNeb/B96qmpudTlCmr6qSIu76jgwN7qSQXjqhd6ugQ/isVqm3M1HsrOzAW6vP5xvrg77lULmdSEt5/XQJLn2uHzEj0uhgZaxh7KyEoqpAL8tyvjGXQ9Wsn8D0jlxWEmCjzCKvVAWOY1nWuxIyA9iDgGduzIHrHVnWAhfl5oAUxL3zYeythLiDxPCDikDKj9V3IMwt9cJ0gJhZs9e7EAgs7y/7/aMS1OuP9h6FsbfnNYerwsHEUIJHn14sSQHz8opanZH/4vXroaFOCUOro6vPL8wCnj9fzVlZDgQWxNIsF8rC7ThexA3Uk/lKCrbhGzcgPKgJY3wcYu+WlvEbNlvnH3fzJzPUoANUcKFSvJYF55gXlgcmlZYmu91O03Rww3al7ko4yqkTgx74rxzegGzYpivzkYqFUCnWvHAMmjZwL59qEqkRyCA/BOGmqKGyBoWYEPDYFsmglA06LMpJ9co9DZ7zc9cHlE0RbpHfPv1syHZVCs9QhDY+vMhP28loAYIghPySdMwpp5iyC/RBkGTTNL+BNvw223Dn0ItnQSAnD5YQD40wh22acEhUUmAPTgftBI/+p4M0+VYJBX8GM/aG1YTiFfS7CkjkZ2gRkiTfzRXSsEOF9Myud+nf6IgBBU9l4y/mWuII+qMArpfjrycxvfM+4PtG7ACF8dEr+KI41tpU2en4zCcFbRwrOXj/DB2rDRUIsYzPlMfzZRU6TxFBvsVLkoQEkjysRMErs+MxXgw0lQIflSf5ri6eoAVBsAgCbKR4eIoqIGkqLT52VNPzSguaSwiQJ2gqs/CMVpsmQQvb2M8EqJ1YF1qgzsf9TRu5x0JRYKygIJTa7Lemq3RNWhGtgMpAGSqeXnNg5rEIlBJAFWVLNZKnSpC4NEWQd5uiBEtaAhcuYIuVOYPQZQdx+eFNn1wuT5WlzWxtbm5tbWUmYDzQHz93J6U1+fHZx3mxB8flnp6UO9eTW88dT+Bzf6osr+d+T0pKMsgnxTzeb0XZ6NguLwHnpMpOtYJ4a2tya1ls+rOIHZ2s5SV22SXv8kdlZWWXvzwe+/5F3rnrwH39cVkizhFFUpOSUo/O/uBUHuBUkiwxRD+tH3V/5HC5hO5zvUcWhsCx9991OIT/AVwXLXUhLDYVAAAAAElFTkSuQmCC"
-
-/***/ }),
+/* 855 */,
 /* 856 */,
 /* 857 */,
 /* 858 */,
 /* 859 */,
 /* 860 */,
 /* 861 */,
 /* 862 */,
 /* 863 */,
@@ -30130,17 +30177,19 @@ var onConnect = exports.onConnect = (() 
 
     yield threadClient.reconfigure({
       observeAsmJS: true,
       wasmBinarySource: supportsWasm
     });
 
     // NOTE: The Worker and Browser Content toolboxes do not have a parent
     // with a listWorkers function
-    if (threadClient._parent && threadClient._parent.listWorkers) {
+    // TODO: there is a listWorkers property, but it is not a function on the
+    // parent. Investigate what it is
+    if (threadClient._parent && typeof threadClient._parent.listWorkers === "function") {
       threadClient._parent.listWorkers().then(function (workers) {
         return actions.setWorkers(workers);
       });
     }
 
     // In Firefox, we need to initially request all of the sources. This
     // usually fires off individual `newSource` notifications as the
     // debugger finds them, but there may be existing sources already in
@@ -31474,24 +31523,28 @@ module.exports = SplitBox;
 
 /***/ }),
 /* 911 */
 /***/ (function(module, exports, __webpack_require__) {
 
 "use strict";
 
 
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
 var React = __webpack_require__(0);
 var ReactDOM = __webpack_require__(4);
 var Draggable = React.createFactory(__webpack_require__(912));
 var dom = React.DOM,
     PropTypes = React.PropTypes;
 
 
-__webpack_require__(1232);
+__webpack_require__(1309);
 
 /**
  * This component represents a Splitter. The splitter supports vertical
  * as well as horizontal mode.
  */
 var SplitBox = React.createClass({
   propTypes: {
     // Custom class name. You can use more names separated by a space.
@@ -31523,84 +31576,85 @@ var SplitBox = React.createClass({
     // Optional style properties passed into the splitbox
     style: PropTypes.object,
     // Optional callback when splitbox resize stops
     onResizeEnd: PropTypes.func
   },
 
   displayName: "SplitBox",
 
-  getDefaultProps() {
+  getDefaultProps: function getDefaultProps() {
     return {
       splitterSize: 5,
       vert: true,
       endPanelControl: false,
       endPanelCollapsed: false,
       startPanelCollapsed: false
     };
   },
 
+
   /**
    * The state stores the current orientation (vertical or horizontal)
    * and the current size (width/height). All these values can change
    * during the component's life time.
    */
-  getInitialState() {
+  getInitialState: function getInitialState() {
     return {
       vert: this.props.vert,
       // We use integers for these properties
       width: parseInt(this.props.initialWidth || this.props.initialSize),
       height: parseInt(this.props.initialHeight || this.props.initialSize)
     };
   },
-
-  componentWillReceiveProps(nextProps) {
+  componentWillReceiveProps: function componentWillReceiveProps(nextProps) {
     if (this.props.vert !== nextProps.vert) {
       this.setState({ vert: nextProps.vert });
     }
   },
 
+
   // Dragging Events
 
   /**
    * Set 'resizing' cursor on entire document during splitter dragging.
    * This avoids cursor-flickering that happens when the mouse leaves
    * the splitter bar area (happens frequently).
    */
-  onStartMove() {
+  onStartMove: function onStartMove() {
     var splitBox = ReactDOM.findDOMNode(this);
     var doc = splitBox.ownerDocument;
     var defaultCursor = doc.documentElement.style.cursor;
     doc.documentElement.style.cursor = this.state.vert ? "ew-resize" : "ns-resize";
 
     splitBox.classList.add("dragging");
 
     this.setState({
       defaultCursor: defaultCursor
     });
   },
-
-  onStopMove() {
+  onStopMove: function onStopMove() {
     var splitBox = ReactDOM.findDOMNode(this);
     var doc = splitBox.ownerDocument;
     doc.documentElement.style.cursor = this.state.defaultCursor;
 
     splitBox.classList.remove("dragging");
 
     if (this.props.onResizeEnd) {
       this.props.onResizeEnd(this.state.vert ? this.state.width : this.state.height);
     }
   },
 
+
   /**
    * Adjust size of the controlled panel. Depending on the current
    * orientation we either remember the width or height of
    * the splitter box.
    */
-  onMove(_ref) {
+  onMove: function onMove(_ref) {
     var movementX = _ref.movementX,
         movementY = _ref.movementY;
 
     var node = ReactDOM.findDOMNode(this);
     var doc = node.ownerDocument;
 
     if (this.props.endPanelControl) {
       // For the end panel we need to increase the width/height when the
@@ -31612,28 +31666,33 @@ var SplitBox = React.createClass({
     if (this.state.vert) {
       var isRtl = doc.dir === "rtl";
       if (isRtl) {
         // In RTL we need to reverse the movement again -- but only for vertical
         // splitters
         movementX = -movementX;
       }
 
-      this.setState((state, props) => ({
-        width: state.width + movementX
-      }));
-    } else {
-      this.setState((state, props) => ({
-        height: state.height + movementY
-      }));
-    }
-  },
+      this.setState(function (state, props) {
+        return {
+          width: state.width + movementX
+        };
+      });
+    } else {
+      this.setState(function (state, props) {
+        return {
+          height: state.height + movementY
+        };
+      });
+    }
+  },
+
 
   // Rendering
-  preparePanelStyles() {
+  preparePanelStyles: function preparePanelStyles() {
     var vert = this.state.vert;
     var _props = this.props,
         minSize = _props.minSize,
         maxSize = _props.maxSize,
         startPanelCollapsed = _props.startPanelCollapsed,
         endPanelControl = _props.endPanelControl,
         endPanelCollapsed = _props.endPanelCollapsed;
 
@@ -31666,20 +31725,19 @@ var SplitBox = React.createClass({
       };
       rightPanelStyle = {
         maxHeight: endPanelControl ? maxSize : null,
         minHeight: endPanelControl ? minSize : null,
         height: startPanelCollapsed ? maxSize : endHeight
       };
     }
 
-    return { leftPanelStyle, rightPanelStyle };
-  },
-
-  render() {
+    return { leftPanelStyle: leftPanelStyle, rightPanelStyle: rightPanelStyle };
+  },
+  render: function render() {
     var vert = this.state.vert;
     var _props2 = this.props,
         startPanelCollapsed = _props2.startPanelCollapsed,
         startPanel = _props2.startPanel,
         endPanel = _props2.endPanel,
         endPanelControl = _props2.endPanelControl,
         splitterSize = _props2.splitterSize,
         endPanelCollapsed = _props2.endPanelCollapsed;
@@ -31697,17 +31755,17 @@ var SplitBox = React.createClass({
     var _preparePanelStyles = this.preparePanelStyles(),
         leftPanelStyle = _preparePanelStyles.leftPanelStyle,
         rightPanelStyle = _preparePanelStyles.rightPanelStyle;
 
     // Calculate splitter size
 
 
     var splitterStyle = {
-      flex: `0 0 ${splitterSize}px`
+      flex: "0 0 " + splitterSize + "px"
     };
 
     return dom.div({
       className: classNames.join(" "),
       style: style
     }, !startPanelCollapsed ? dom.div({
       className: endPanelControl ? "uncontrolled" : "controlled",
       style: leftPanelStyle
@@ -31749,40 +31807,37 @@ var Draggable = React.createClass({
   propTypes: {
     onMove: PropTypes.func.isRequired,
     onStart: PropTypes.func,
     onStop: PropTypes.func,
     style: PropTypes.object,
     className: PropTypes.string
   },
 
-  startDragging(ev) {
+  startDragging: function startDragging(ev) {
     ev.preventDefault();
     var doc = ReactDOM.findDOMNode(this).ownerDocument;
     doc.addEventListener("mousemove", this.onMove);
     doc.addEventListener("mouseup", this.onUp);
     this.props.onStart && this.props.onStart();
   },
-
-  onMove(ev) {
+  onMove: function onMove(ev) {
     ev.preventDefault();
     // We pass the whole event because we don't know which properties
     // the callee needs.
     this.props.onMove(ev);
   },
-
-  onUp(ev) {
+  onUp: function onUp(ev) {
     ev.preventDefault();
     var doc = ReactDOM.findDOMNode(this).ownerDocument;
     doc.removeEventListener("mousemove", this.onMove);
     doc.removeEventListener("mouseup", this.onUp);
     this.props.onStop && this.props.onStop();
   },
-
-  render() {
+  render: function render() {
     return dom.div({
       style: this.props.style,
       className: this.props.className,
       onMouseDown: this.startDragging
     });
   }
 });
 
@@ -32411,17 +32466,17 @@ module.exports = {
 
 "use strict";
 
 
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-__webpack_require__(1250);
+__webpack_require__(1324);
 
 // Load all existing rep templates
 var Undefined = __webpack_require__(929);
 var Null = __webpack_require__(930);
 var StringRep = __webpack_require__(931);
 var LongStringRep = __webpack_require__(932);
 var Number = __webpack_require__(933);
 var ArrayRep = __webpack_require__(934);
@@ -36029,17 +36084,17 @@ module.exports = {
   supportsObject,
   maxLengthMap
 };
 
 /***/ }),
 /* 960 */
 /***/ (function(module, exports) {
 
-module.exports = "# This Source Code Form is subject to the terms of the Mozilla Public\n# License, v. 2.0. If a copy of the MPL was not distributed with this\n# file, You can obtain one at http://mozilla.org/MPL/2.0/.\n\n# LOCALIZATION NOTE These strings are used inside the Debugger\n# which is available from the Web Developer sub-menu -> 'Debugger'.\n# The correct localization of this file might be to keep it in\n# English, or another language commonly spoken among web developers.\n# You want to make that choice consistent across the developer tools.\n# A good criteria is the language in which you'd find the best\n# documentation on web development on the web.\n\n# LOCALIZATION NOTE (collapsePanes): This is the tooltip for the button\n# that collapses the left and right panes in the debugger UI.\ncollapsePanes=Collapse panes\n\n# LOCALIZATION NOTE (copySource): This is the text that appears in the\n# context menu to copy the selected source of file open.\ncopySource=Copy\ncopySource.accesskey=y\n\n# LOCALIZATION NOTE (copySourceUri2): This is the text that appears in the\n# context menu to copy the source URI of file open.\ncopySourceUri2=Copy source URI\ncopySourceUri2.accesskey=u\n\n# LOCALIZATION NOTE (copyFunction): This is the text that appears in the\n# context menu to copy the function the user selected\ncopyFunction.label=Copy function\ncopyFunction.accesskey=F\n\n# LOCALIZATION NOTE (copyStackTrace): This is the text that appears in the\n# context menu to copy the stack trace methods, file names and row number.\ncopyStackTrace=Copy stack trace\ncopyStackTrace.accesskey=c\n\n# LOCALIZATION NOTE (expandPanes): This is the tooltip for the button\n# that expands the left and right panes in the debugger UI.\nexpandPanes=Expand panes\n\n# LOCALIZATION NOTE (pauseButtonTooltip): The tooltip that is displayed for the pause\n# button when the debugger is in a running state.\npauseButtonTooltip=Pause %S\n\n# LOCALIZATION NOTE (pausePendingButtonTooltip): The tooltip that is displayed for\n# the pause button after it's been clicked but before the next JavaScript to run.\npausePendingButtonTooltip=Waiting for next execution\n\n# LOCALIZATION NOTE (resumeButtonTooltip): The label that is displayed on the pause\n# button when the debugger is in a paused state.\nresumeButtonTooltip=Resume %S\n\n# LOCALIZATION NOTE (stepOverTooltip): The label that is displayed on the\n# button that steps over a function call.\nstepOverTooltip=Step over %S\n\n# LOCALIZATION NOTE (stepInTooltip): The label that is displayed on the\n# button that steps into a function call.\nstepInTooltip=Step in %S\n\n# LOCALIZATION NOTE (stepOutTooltip): The label that is displayed on the\n# button that steps out of a function call.\nstepOutTooltip=Step out %S\n\n# LOCALIZATION NOTE (workersHeader): The text to display in the events\n# header.\nworkersHeader=Workers\n\n# LOCALIZATION NOTE (noWorkersText): The text to display in the workers list\n# when there are no workers.\nnoWorkersText=This page has no workers.\n\n# LOCALIZATION NOTE (noSourcesText): The text to display in the sources list\n# when there are no sources.\nnoSourcesText=This page has no sources.\n\n# LOCALIZATION NOTE (noEventListenersText): The text to display in the events tab\n# when there are no events.\nnoEventListenersText=No event listeners to display.\n\n# LOCALIZATION NOTE (eventListenersHeader): The text to display in the events\n# header.\neventListenersHeader=Event listeners\n\n# LOCALIZATION NOTE (noStackFramesText): The text to display in the call stack tab\n# when there are no stack frames.\nnoStackFramesText=No stack frames to display\n\n# LOCALIZATION NOTE (eventCheckboxTooltip): The tooltip text to display when\n# the user hovers over the checkbox used to toggle an event breakpoint.\neventCheckboxTooltip=Toggle breaking on this event\n\n# LOCALIZATION NOTE (eventOnSelector): The text to display in the events tab\n# for every event item, between the event type and event selector.\neventOnSelector=on\n\n# LOCALIZATION NOTE (eventInSource): The text to display in the events tab\n# for every event item, between the event selector and listener's owner source.\neventInSource=in\n\n# LOCALIZATION NOTE (eventNodes): The text to display in the events tab when\n# an event is listened on more than one target node.\neventNodes=%S nodes\n\n# LOCALIZATION NOTE (eventNative): The text to display in the events tab when\n# a listener is added from plugins, thus getting translated to native code.\neventNative=[native code]\n\n# LOCALIZATION NOTE (*Events): The text to display in the events tab for\n# each group of sub-level event entries.\nanimationEvents=Animation\naudioEvents=Audio\nbatteryEvents=Battery\nclipboardEvents=Clipboard\ncompositionEvents=Composition\ndeviceEvents=Device\ndisplayEvents=Display\ndragAndDropEvents=Drag and Drop\ngamepadEvents=Gamepad\nindexedDBEvents=IndexedDB\ninteractionEvents=Interaction\nkeyboardEvents=Keyboard\nmediaEvents=HTML5 Media\nmouseEvents=Mouse\nmutationEvents=Mutation\nnavigationEvents=Navigation\npointerLockEvents=Pointer Lock\nsensorEvents=Sensor\nstorageEvents=Storage\ntimeEvents=Time\ntouchEvents=Touch\notherEvents=Other\n\n# LOCALIZATION NOTE (blackboxCheckboxTooltip2): The tooltip text to display when\n# the user hovers over the checkbox used to toggle blackboxing its associated\n# source.\nblackboxCheckboxTooltip2=Toggle blackboxing\n\n# LOCALIZATION NOTE (sources.search.key2): Key shortcut to open the search for\n# searching all the source files the debugger has seen.\nsources.search.key2=CmdOrCtrl+P\n\n# LOCALIZATION NOTE (sources.search.alt.key): A second key shortcut to open the\n# search for searching all the source files the debugger has seen.\nsources.search.alt.key=CmdOrCtrl+O\n\n# LOCALIZATION NOTE (projectTextSearch.key): A key shortcut to open the\n# full project text search for searching all the files the debugger has seen.\nprojectTextSearch.key=CmdOrCtrl+Shift+F\n\n# LOCALIZATION NOTE (functionSearch.key): A key shortcut to open the\n# modal for searching functions in a file.\nfunctionSearch.key=CmdOrCtrl+Shift+O\n\n# LOCALIZATION NOTE (toggleBreakpoint.key): A key shortcut to toggle\n# breakpoints.\ntoggleBreakpoint.key=CmdOrCtrl+B\n\n# LOCALIZATION NOTE (toggleCondPanel.key): A key shortcut to toggle\n# the conditional breakpoint panel.\ntoggleCondPanel.key=CmdOrCtrl+Shift+B\n\n# LOCALIZATION NOTE (stepOut.key): A key shortcut to\n# step out.\nstepOut.key=Shift+F11\n\n# LOCALIZATION NOTE (shortcuts.header.editor): Sections header in\n# the shortcuts modal for keyboard shortcuts related to editing.\nshortcuts.header.editor=Editor\n\n# LOCALIZATION NOTE (shortcuts.header.stepping): Sections header in\n# the shortcuts modal for keyboard shortcuts related to stepping.\nshortcuts.header.stepping=Stepping\n\n# LOCALIZATION NOTE (shortcuts.header.search): Sections header in\n# the shortcuts modal for keyboard shortcuts related to search.\nshortcuts.header.search=Search\n\n# LOCALIZATION NOTE (projectTextSearch.placeholder): A placeholder shown\n# when searching across all of the files in a project.\nprojectTextSearch.placeholder=Find in files…\n\n# LOCALIZATION NOTE (projectTextSearch.noResults): The center pane Text Search\n# message when the query did not match any text of all files in a project.\nprojectTextSearch.noResults=No results found\n\n# LOCALIZATION NOTE (sources.noSourcesAvailable): Text shown when the debugger\n# does not have any sources.\nsources.noSourcesAvailable=This page has no sources\n\n# LOCALIZATION NOTE (sourceSearch.search.key2): Key shortcut to open the search\n# for searching within a the currently opened files in the editor\nsourceSearch.search.key2=CmdOrCtrl+F\n\n# LOCALIZATION NOTE (sourceSearch.search.placeholder): placeholder text in\n# the source search input bar\nsourceSearch.search.placeholder=Search in file…\n\n# LOCALIZATION NOTE (sourceSearch.search.again.key2): Key shortcut to highlight\n# the next occurrence of the last search triggered from a source search\nsourceSearch.search.again.key2=CmdOrCtrl+G\n\n# LOCALIZATION NOTE (sourceSearch.search.againPrev.key2): Key shortcut to highlight\n# the previous occurrence of the last search triggered from a source search\nsourceSearch.search.againPrev.key2=CmdOrCtrl+Shift+G\n\n# LOCALIZATION NOTE (sourceSearch.resultsSummary1): Shows a summary of\n# the number of matches for autocomplete\nsourceSearch.resultsSummary1=%d results\n\n# LOCALIZATION NOTE (noMatchingStringsText): The text to display in the\n# global search results when there are no matching strings after filtering.\nnoMatchingStringsText=No matches found\n\n# LOCALIZATION NOTE (emptySearchText): This is the text that appears in the\n# filter text box when it is empty and the scripts container is selected.\nemptySearchText=Search scripts (%S)\n\n# LOCALIZATION NOTE (emptyVariablesFilterText): This is the text that\n# appears in the filter text box for the variables view container.\nemptyVariablesFilterText=Filter variables\n\n# LOCALIZATION NOTE (emptyPropertiesFilterText): This is the text that\n# appears in the filter text box for the editor's variables view bubble.\nemptyPropertiesFilterText=Filter properties\n\n# LOCALIZATION NOTE (searchPanelFilter): This is the text that appears in the\n# filter panel popup for the filter scripts operation.\nsearchPanelFilter=Filter scripts (%S)\n\n# LOCALIZATION NOTE (searchPanelGlobal): This is the text that appears in the\n# filter panel popup for the global search operation.\nsearchPanelGlobal=Search in all files (%S)\n\n# LOCALIZATION NOTE (searchPanelFunction): This is the text that appears in the\n# filter panel popup for the function search operation.\nsearchPanelFunction=Search for function definition (%S)\n\n# LOCALIZATION NOTE (searchPanelToken): This is the text that appears in the\n# filter panel popup for the token search operation.\nsearchPanelToken=Find in this file (%S)\n\n# LOCALIZATION NOTE (searchPanelGoToLine): This is the text that appears in the\n# filter panel popup for the line search operation.\nsearchPanelGoToLine=Go to line (%S)\n\n# LOCALIZATION NOTE (searchPanelVariable): This is the text that appears in the\n# filter panel popup for the variables search operation.\nsearchPanelVariable=Filter variables (%S)\n\n# LOCALIZATION NOTE (breakpointMenuItem): The text for all the elements that\n# are displayed in the breakpoints menu item popup.\nbreakpointMenuItem.setConditional=Configure conditional breakpoint\nbreakpointMenuItem.enableSelf2.label=Enable\nbreakpointMenuItem.enableSelf2.accesskey=E\nbreakpointMenuItem.disableSelf2.label=Disable\nbreakpointMenuItem.disableSelf2.accesskey=D\nbreakpointMenuItem.deleteSelf2.label=Remove\nbreakpointMenuItem.deleteSelf2.accesskey=R\nbreakpointMenuItem.enableOthers2.label=Enable others\nbreakpointMenuItem.enableOthers2.accesskey=o\nbreakpointMenuItem.disableOthers2.label=Disable others\nbreakpointMenuItem.disableOthers2.accesskey=s\nbreakpointMenuItem.deleteOthers2.label=Remove others\nbreakpointMenuItem.deleteOthers2.accesskey=h\nbreakpointMenuItem.enableAll2.label=Enable all\nbreakpointMenuItem.enableAll2.accesskey=b\nbreakpointMenuItem.disableAll2.label=Disable all\nbreakpointMenuItem.disableAll2.accesskey=k\nbreakpointMenuItem.deleteAll2.label=Remove all\nbreakpointMenuItem.deleteAll2.accesskey=a\nbreakpointMenuItem.removeCondition2.label=Remove condition\nbreakpointMenuItem.removeCondition2.accesskey=c\nbreakpointMenuItem.addCondition2.label=Add condition\nbreakpointMenuItem.addCondition2.accesskey=A\nbreakpointMenuItem.editCondition2.label=Edit condition\nbreakpointMenuItem.editCondition2.accesskey=n\nbreakpointMenuItem.enableSelf=Enable breakpoint\nbreakpointMenuItem.enableSelf.accesskey=E\nbreakpointMenuItem.disableSelf=Disable breakpoint\nbreakpointMenuItem.disableSelf.accesskey=D\nbreakpointMenuItem.deleteSelf=Remove breakpoint\nbreakpointMenuItem.deleteSelf.accesskey=R\nbreakpointMenuItem.enableOthers=Enable others\nbreakpointMenuItem.enableOthers.accesskey=o\nbreakpointMenuItem.disableOthers=Disable others\nbreakpointMenuItem.disableOthers.accesskey=s\nbreakpointMenuItem.deleteOthers=Remove others\nbreakpointMenuItem.deleteOthers.accesskey=h\nbreakpointMenuItem.enableAll=Enable all breakpoints\nbreakpointMenuItem.enableAll.accesskey=b\nbreakpointMenuItem.disableAll=Disable all breakpoints\nbreakpointMenuItem.disableAll.accesskey=k\nbreakpointMenuItem.deleteAll=Remove all breakpoints\nbreakpointMenuItem.deleteAll.accesskey=a\nbreakpointMenuItem.removeCondition.label=Remove breakpoint condition\nbreakpointMenuItem.removeCondition.accesskey=c\nbreakpointMenuItem.editCondition.label=Edit breakpoint condition\nbreakpointMenuItem.editCondition.accesskey=n\n\n# LOCALIZATION NOTE (breakpoints.header): Breakpoints right sidebar pane header.\nbreakpoints.header=Breakpoints\n\n# LOCALIZATION NOTE (breakpoints.none): The text that appears when there are\n# no breakpoints present\nbreakpoints.none=No breakpoints\n\n# LOCALIZATION NOTE (breakpoints.enable): The text that may appear as a tooltip\n# when hovering over the 'disable breakpoints' switch button in right sidebar\nbreakpoints.enable=Enable breakpoints\n\n# LOCALIZATION NOTE (breakpoints.disable): The text that may appear as a tooltip\n# when hovering over the 'disable breakpoints' switch button in right sidebar\nbreakpoints.disable=Disable breakpoints\n\n# LOCALIZATION NOTE (breakpoints.removeBreakpointTooltip): The tooltip that is displayed\n# for remove breakpoint button in right sidebar\nbreakpoints.removeBreakpointTooltip=Remove breakpoint\n\n# LOCALIZATION NOTE (callStack.header): Call Stack right sidebar pane header.\ncallStack.header=Call stack\n\n# LOCALIZATION NOTE (callStack.notPaused): Call Stack right sidebar pane\n# message when not paused.\ncallStack.notPaused=Not paused\n\n# LOCALIZATION NOTE (callStack.collapse): Call Stack right sidebar pane\n# message to hide some of the frames that are shown.\ncallStack.collapse=Collapse rows\n\n# LOCALIZATION NOTE (callStack.expand): Call Stack right sidebar pane\n# message to show more of the frames.\ncallStack.expand=Expand rows\n\n# LOCALIZATION NOTE (editor.searchResults): Editor Search bar message\n# for the summarizing the selected search result. e.g. 5 of 10 results.\neditor.searchResults=%d of %d results\n\n# LOCALIZATION NOTE (sourceSearch.singleResult): Copy shown when there is one result.\neditor.singleResult=1 result\n\n# LOCALIZATION NOTE (editor.noResults): Editor Search bar message\n# for when no results found.\neditor.noResults=No results\n\n# LOCALIZATION NOTE (editor.searchResults.nextResult): Editor Search bar\n# tooltip for traversing to the Next Result\neditor.searchResults.nextResult=Next result\n\n# LOCALIZATION NOTE (editor.searchResults.prevResult): Editor Search bar\n# tooltip for traversing to the Previous Result\neditor.searchResults.prevResult=Previous result\n\n# LOCALIZATION NOTE (editor.searchTypeToggleTitle): Search bar title for\n# toggling search type buttons(function search, variable search)\neditor.searchTypeToggleTitle=Search for:\n\n# LOCALIZATION NOTE (editor.continueToHere.label): Editor gutter context\n# menu item for jumping to a new paused location\neditor.continueToHere.label=Continue to here\neditor.continueToHere.accesskey=H\n\n# LOCALIZATION NOTE (editor.addBreakpoint): Editor gutter context menu item\n# for adding a breakpoint on a line.\neditor.addBreakpoint=Add breakpoint\n\n# LOCALIZATION NOTE (editor.disableBreakpoint): Editor gutter context menu item\n# for disabling a breakpoint on a line.\neditor.disableBreakpoint=Disable breakpoint\n\n# LOCALIZATION NOTE (editor.enableBreakpoint): Editor gutter context menu item\n# for enabling a breakpoint on a line.\neditor.enableBreakpoint=Enable breakpoint\n\n# LOCALIZATION NOTE (editor.removeBreakpoint): Editor gutter context menu item\n# for removing a breakpoint on a line.\neditor.removeBreakpoint=Remove breakpoint\n\n# LOCALIZATION NOTE (editor.editBreakpoint): Editor gutter context menu item\n# for setting a breakpoint condition on a line.\neditor.editBreakpoint=Edit breakpoint\n\n# LOCALIZATION NOTE (editor.addConditionalBreakpoint): Editor gutter context\n# menu item for adding a breakpoint condition on a line.\neditor.addConditionalBreakpoint=Add conditional breakpoint\n\n# LOCALIZATION NOTE (editor.conditionalPanel.placeholder): Placeholder text for\n# input element inside ConditionalPanel component\neditor.conditionalPanel.placeholder=This breakpoint will pause when the expression is true\n\n# LOCALIZATION NOTE (editor.conditionalPanel.placeholder): Tooltip text for\n# close button inside ConditionalPanel component\neditor.conditionalPanel.close=Cancel edit breakpoint and close\n\n# LOCALIZATION NOTE (editor.jumpToMappedLocation1): Context menu item\n# for navigating to a source mapped location\neditor.jumpToMappedLocation1=Jump to %S location\n\n# LOCALIZATION NOTE (framework.disableGrouping): This is the text that appears in the\n# context menu to disable framework grouping.\nframework.disableGrouping=Disable framework grouping\nframework.disableGrouping.accesskey=u\n\n# LOCALIZATION NOTE (framework.enableGrouping): This is the text that appears in the\n# context menu to enable framework grouping.\nframework.enableGrouping=Enable framework grouping\nframework.enableGrouping.accesskey=u\n\n# LOCALIZATION NOTE (generated): Source Map term for a server source location\ngenerated=Generated\n\n# LOCALIZATION NOTE (original): Source Map term for a debugger UI source location\noriginal=original\n\n# LOCALIZATION NOTE (expressions.placeholder): Placeholder text for expression\n# input element\nexpressions.placeholder=Add watch expression\n\n# LOCALIZATION NOTE (sourceTabs.closeTab): Editor source tab context menu item\n# for closing the selected tab below the mouse.\nsourceTabs.closeTab=Close tab\nsourceTabs.closeTab.accesskey=c\n\n# LOCALIZATION NOTE (sourceTabs.closeOtherTabs): Editor source tab context menu item\n# for closing the other tabs.\nsourceTabs.closeOtherTabs=Close other tabs\nsourceTabs.closeOtherTabs.accesskey=o\n\n# LOCALIZATION NOTE (sourceTabs.closeTabsToEnd): Editor source tab context menu item\n# for closing the tabs to the end (the right for LTR languages) of the selected tab.\nsourceTabs.closeTabsToEnd=Close tabs to the right\nsourceTabs.closeTabsToEnd.accesskey=e\n\n# LOCALIZATION NOTE (sourceTabs.closeAllTabs): Editor source tab context menu item\n# for closing all tabs.\nsourceTabs.closeAllTabs=Close all tabs\nsourceTabs.closeAllTabs.accesskey=a\n\n# LOCALIZATION NOTE (sourceTabs.revealInTree): Editor source tab context menu item\n# for revealing source in tree.\nsourceTabs.revealInTree=Reveal in tree\nsourceTabs.revealInTree.accesskey=r\n\n# LOCALIZATION NOTE (sourceTabs.prettyPrint): Editor source tab context menu item\n# for pretty printing the source.\nsourceTabs.prettyPrint=Pretty print source\nsourceTabs.prettyPrint.accesskey=p\n\n# LOCALIZATION NOTE (sourceFooter.blackbox): Tooltip text associated\n# with the blackbox button\nsourceFooter.blackbox=Blackbox source\nsourceFooter.blackbox.accesskey=B\n\n# LOCALIZATION NOTE (sourceFooter.unblackbox): Tooltip text associated\n# with the blackbox button\nsourceFooter.unblackbox=Unblackbox source\nsourceFooter.unblackbox.accesskey=b\n\n# LOCALIZATION NOTE (sourceFooter.blackboxed): Text associated\n# with a blackboxed source\nsourceFooter.blackboxed=Blackboxed source\n\n# LOCALIZATION NOTE (sourceFooter.codeCoverage): Text associated\n# with a code coverage button\nsourceFooter.codeCoverage=Code coverage\n\n# LOCALIZATION NOTE (sourceTabs.closeTabButtonTooltip): The tooltip that is displayed\n# for close tab button in source tabs.\nsourceTabs.closeTabButtonTooltip=Close tab\n\n# LOCALIZATION NOTE (sourceTabs.newTabButtonTooltip): The tooltip that is displayed for\n# new tab button in source tabs.\nsourceTabs.newTabButtonTooltip=Search for sources (%S)\n\n# LOCALIZATION NOTE (scopes.header): Scopes right sidebar pane header.\nscopes.header=Scopes\n\n# LOCALIZATION NOTE (scopes.notAvailable): Scopes right sidebar pane message\n# for when the debugger is paused, but there isn't pause data.\nscopes.notAvailable=Scopes unavailable\n\n# LOCALIZATION NOTE (scopes.notPaused): Scopes right sidebar pane message\n# for when the debugger is not paused.\nscopes.notPaused=Not paused\n\n# LOCALIZATION NOTE (scopes.block): Refers to a block of code in\n# the scopes pane when the debugger is paused.\nscopes.block=Block\n\n# LOCALIZATION NOTE (sources.header): Sources left sidebar header\nsources.header=Sources\n\n# LOCALIZATION NOTE (outline.header): Outline left sidebar header\noutline.header=Outline\n\n# LOCALIZATION NOTE (outline.noFunctions): Outline text when there are no functions to display\noutline.noFunctions=No functions\n\n# LOCALIZATION NOTE (sources.search): Sources left sidebar prompt\n# e.g. Cmd+P to search. On a mac, we use the command unicode character.\n# On windows, it's ctrl.\nsources.search=%S to search\n\n# LOCALIZATION NOTE (watchExpressions.header): Watch Expressions right sidebar\n# pane header.\nwatchExpressions.header=Watch expressions\n\n# LOCALIZATION NOTE (watchExpressions.refreshButton): Watch Expressions header\n# button for refreshing the expressions.\nwatchExpressions.refreshButton=Refresh\n\n# LOCALIZATION NOTE (welcome.search): The center pane welcome panel's\n# search prompt. e.g. cmd+p to search for files. On windows, it's ctrl, on\n# a mac we use the unicode character.\nwelcome.search=%S to search for sources\n\n# LOCALIZATION NOTE (welcome.findInFiles): The center pane welcome panel's\n# search prompt. e.g. cmd+f to search for files. On windows, it's ctrl+shift+f, on\n# a mac we use the unicode character.\nwelcome.findInFiles=%S to find in files\n\n# LOCALIZATION NOTE (welcome.searchFunction): Label displayed in the welcome\n# panel. %S is replaced by the keyboard shortcut to search for functions.\nwelcome.searchFunction=%S to search for functions in file\n\n# LOCALIZATION NOTE (sourceSearch.search): The center pane Source Search\n# prompt for searching for files.\nsourceSearch.search=Search sources…\n\n# LOCALIZATION NOTE (sourceSearch.noResults): The center pane Source Search\n# message when the query did not match any of the sources.\nsourceSearch.noResults2=No results found\n\n# LOCALIZATION NOTE (ignoreExceptions): The pause on exceptions button tooltip\n# when the debugger will not pause on exceptions.\nignoreExceptions=Ignore exceptions. Click to pause on uncaught exceptions\n\n# LOCALIZATION NOTE (pauseOnUncaughtExceptions): The pause on exceptions button\n# tooltip when the debugger will pause on uncaught exceptions.\npauseOnUncaughtExceptions=Pause on uncaught exceptions. Click to pause on all exceptions\n\n# LOCALIZATION NOTE (pauseOnExceptions): The pause on exceptions button tooltip\n# when the debugger will pause on all exceptions.\npauseOnExceptions=Pause on all exceptions. Click to ignore exceptions\n\n# LOCALIZATION NOTE (loadingText): The text that is displayed in the script\n# editor when the loading process has started but there is no file to display\n# yet.\nloadingText=Loading\\u2026\n\n# LOCALIZATION NOTE (errorLoadingText3): The text that is displayed in the debugger\n# viewer when there is an error loading a file\nerrorLoadingText3=Error loading this URI: %S\n\n# LOCALIZATION NOTE (addWatchExpressionText): The text that is displayed in the\n# watch expressions list to add a new item.\naddWatchExpressionText=Add watch expression\n\n# LOCALIZATION NOTE (addWatchExpressionButton): The button that is displayed in the\n# variables view popup.\naddWatchExpressionButton=Watch\n\n# LOCALIZATION NOTE (emptyVariablesText): The text that is displayed in the\n# variables pane when there are no variables to display.\nemptyVariablesText=No variables to display\n\n# LOCALIZATION NOTE (scopeLabel): The text that is displayed in the variables\n# pane as a header for each variable scope (e.g. \"Global scope, \"With scope\",\n# etc.).\nscopeLabel=%S scope\n\n# LOCALIZATION NOTE (watchExpressionsScopeLabel): The name of the watch\n# expressions scope. This text is displayed in the variables pane as a header for\n# the watch expressions scope.\nwatchExpressionsScopeLabel=Watch expressions\n\n# LOCALIZATION NOTE (globalScopeLabel): The name of the global scope. This text\n# is added to scopeLabel and displayed in the variables pane as a header for\n# the global scope.\nglobalScopeLabel=Global\n\n# LOCALIZATION NOTE (variablesViewErrorStacktrace): This is the text that is\n# shown before the stack trace in an error.\nvariablesViewErrorStacktrace=Stack trace:\n\n# LOCALIZATION NOTE (variablesViewMoreObjects): the text that is displayed\n# when you have an object preview that does not show all of the elements. At the end of the list\n# you see \"N more...\" in the web console output.\n# This is a semi-colon list of plural forms.\n# See: http://developer.mozilla.org/en/docs/Localization_and_Plurals\n# #1 number of remaining items in the object\n# example: 3 more…\nvariablesViewMoreObjects=#1 more…;#1 more…\n\n# LOCALIZATION NOTE (variablesEditableNameTooltip): The text that is displayed\n# in the variables list on an item with an editable name.\nvariablesEditableNameTooltip=Double click to edit\n\n# LOCALIZATION NOTE (variablesEditableValueTooltip): The text that is displayed\n# in the variables list on an item with an editable value.\nvariablesEditableValueTooltip=Click to change value\n\n# LOCALIZATION NOTE (variablesCloseButtonTooltip): The text that is displayed\n# in the variables list on an item which can be removed.\nvariablesCloseButtonTooltip=Click to remove\n\n# LOCALIZATION NOTE (variablesEditButtonTooltip): The text that is displayed\n# in the variables list on a getter or setter which can be edited.\nvariablesEditButtonTooltip=Click to set value\n\n# LOCALIZATION NOTE (variablesEditableValueTooltip): The text that is displayed\n# in a tooltip on the \"open in inspector\" button in the the variables list for a\n# DOMNode item.\nvariablesDomNodeValueTooltip=Click to select the node in the inspector\n\n# LOCALIZATION NOTE (configurable|...|Tooltip): The text that is displayed\n# in the variables list on certain variables or properties as tooltips.\n# Expanations of what these represent can be found at the following links:\n# https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty\n# https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object/isExtensible\n# https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object/isFrozen\n# https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object/isSealed\n# It's probably best to keep these in English.\nconfigurableTooltip=configurable\nenumerableTooltip=enumerable\nwritableTooltip=writable\nfrozenTooltip=frozen\nsealedTooltip=sealed\nextensibleTooltip=extensible\noverriddenTooltip=overridden\nWebIDLTooltip=WebIDL\n\n# LOCALIZATION NOTE (variablesSeparatorLabel): The text that is displayed\n# in the variables list as a separator between the name and value.\nvariablesSeparatorLabel=:\n\n# LOCALIZATION NOTE (watchExpressionsSeparatorLabel2): The text that is displayed\n# in the watch expressions list as a separator between the code and evaluation.\nwatchExpressionsSeparatorLabel2=\\u0020→\n\n# LOCALIZATION NOTE (functionSearchSeparatorLabel): The text that is displayed\n# in the functions search panel as a separator between function's inferred name\n# and its real name (if available).\nfunctionSearchSeparatorLabel=←\n\n# LOCALIZATION NOTE(symbolSearch.search.functionsPlaceholder): The placeholder\n# text displayed when the user searches for functions in a file\nsymbolSearch.search.functionsPlaceholder=Search functions…\n\n# LOCALIZATION NOTE(symbolSearch.search.variablesPlaceholder): The placeholder\n# text displayed when the user searches for variables in a file\nsymbolSearch.search.variablesPlaceholder=Search variables…\n\n# LOCALIZATION NOTE(symbolSearch.search.key2): The Key Shortcut for\n# searching for a function or variable\nsymbolSearch.search.key2=CmdOrCtrl+Shift+O\n\n# LOCALIZATION NOTE(symbolSearch.searchModifier.modifiersLabel): A label\n# preceding the group of modifiers\nsymbolSearch.searchModifier.modifiersLabel=Modifiers:\n\n# LOCALIZATION NOTE(symbolSearch.searchModifier.regex): A search option\n# when searching text in a file\nsymbolSearch.searchModifier.regex=Regex\n\n# LOCALIZATION NOTE(symbolSearch.searchModifier.caseSensitive): A search option\n# when searching text in a file\nsymbolSearch.searchModifier.caseSensitive=Case sensitive\n\n# LOCALIZATION NOTE(symbolSearch.searchModifier.wholeWord): A search option\n# when searching text in a file\nsymbolSearch.searchModifier.wholeWord=Whole word\n\n# LOCALIZATION NOTE (resumptionOrderPanelTitle): This is the text that appears\n# as a description in the notification panel popup, when multiple debuggers are\n# open in separate tabs and the user tries to resume them in the wrong order.\n# The substitution parameter is the URL of the last paused window that must be\n# resumed first.\nresumptionOrderPanelTitle=There are one or more paused debuggers. Please resume the most-recently paused debugger first at: %S\n\nvariablesViewOptimizedOut=(optimized away)\nvariablesViewUninitialized=(uninitialized)\nvariablesViewMissingArgs=(unavailable)\n\nanonymousSourcesLabel=Anonymous sources\n\nexperimental=This is an experimental feature\n\n# LOCALIZATION NOTE (whyPaused.debuggerStatement): The text that is displayed\n# in a info block explaining how the debugger is currently paused due to a `debugger`\n# statement in the code\nwhyPaused.debuggerStatement=Paused on debugger statement\n\n# LOCALIZATION NOTE (whyPaused.breakpoint): The text that is displayed\n# in a info block explaining how the debugger is currently paused on a breakpoint\nwhyPaused.breakpoint=Paused on breakpoint\n\n# LOCALIZATION NOTE (whyPaused.exception): The text that is displayed\n# in a info block explaining how the debugger is currently paused on an exception\nwhyPaused.exception=Paused on exception\n\n# LOCALIZATION NOTE (whyPaused.resumeLimit): The text that is displayed\n# in a info block explaining how the debugger is currently paused while stepping\n# in or out of the stack\nwhyPaused.resumeLimit=Paused while stepping\n\n# LOCALIZATION NOTE (whyPaused.pauseOnDOMEvents): The text that is displayed\n# in a info block explaining how the debugger is currently paused on a\n# dom event\nwhyPaused.pauseOnDOMEvents=Paused on event listener\n\n# LOCALIZATION NOTE (whyPaused.breakpointConditionThrown): The text that is displayed\n# in an info block when evaluating a conditional breakpoint throws an error\nwhyPaused.breakpointConditionThrown=Error with conditional breakpoint\n\n# LOCALIZATION NOTE (whyPaused.xhr): The text that is displayed\n# in a info block explaining how the debugger is currently paused on an\n# xml http request\nwhyPaused.xhr=Paused on XMLHttpRequest\n\n# LOCALIZATION NOTE (whyPaused.promiseRejection): The text that is displayed\n# in a info block explaining how the debugger is currently paused on a\n# promise rejection\nwhyPaused.promiseRejection=Paused on promise rejection\n\n# LOCALIZATION NOTE (whyPaused.assert): The text that is displayed\n# in a info block explaining how the debugger is currently paused on an\n# assert\nwhyPaused.assert=Paused on assertion\n\n# LOCALIZATION NOTE (whyPaused.debugCommand): The text that is displayed\n# in a info block explaining how the debugger is currently paused on a\n# debugger statement\nwhyPaused.debugCommand=Paused on debugged function\n\n# LOCALIZATION NOTE (whyPaused.other): The text that is displayed\n# in a info block explaining how the debugger is currently paused on an event\n# listener breakpoint set\nwhyPaused.other=Debugger paused\n\n# LOCALIZATION NOTE (ctrl): The text that is used for documenting\n# keyboard shortcuts that use the control key\nctrl=Ctrl\n\n# LOCALIZATION NOTE (anonymous): The text that is displayed when the\n# display name is null.\nanonymous=(anonymous)\n\n# LOCALIZATION NOTE (shortcuts.toggleBreakpoint): text describing\n# keyboard shortcut action for toggling breakpoint\nshortcuts.toggleBreakpoint=Toggle Breakpoint\n\n# LOCALIZATION NOTE (shortcuts.toggleCondPanel): text describing\n# keyboard shortcut action for toggling conditional panel keyboard\nshortcuts.toggleCondPanel=Toggle Conditional Panel\n\n# LOCALIZATION NOTE (shortcuts.pauseOrResume): text describing\n# keyboard shortcut action for pause of resume\nshortcuts.pauseOrResume=Pause/Resume\n\n# LOCALIZATION NOTE (shortcuts.stepOver): text describing\n# keyboard shortcut action for stepping over\nshortcuts.stepOver=Step Over\n\n# LOCALIZATION NOTE (shortcuts.stepIn): text describing\n# keyboard shortcut action for stepping in\nshortcuts.stepIn=Step In\n\n# LOCALIZATION NOTE (shortcuts.stepOut): text describing\n# keyboard shortcut action for stepping out\nshortcuts.stepOut=Step Out\n\n# LOCALIZATION NOTE (shortcuts.fileSearch): text describing\n# keyboard shortcut action for source file search\nshortcuts.fileSearch=Source File Search\n\n# LOCALIZATION NOTE (shortcuts.searchAgain): text describing\n# keyboard shortcut action for searching again\nshortcuts.searchAgain=Search Again\n\n# LOCALIZATION NOTE (shortcuts.projectSearch): text describing\n# keyboard shortcut action for full project search\nshortcuts.projectSearch=Full Project Search\n\n# LOCALIZATION NOTE (shortcuts.functionSearch): text describing\n# keyboard shortcut action for function search\nshortcuts.functionSearch=Function Search\n\n# LOCALIZATION NOTE (shortcuts.buttonName): text describing\n# keyboard shortcut button text\nshortcuts.buttonName=Keyboard shortcuts\n"
+module.exports = "# This Source Code Form is subject to the terms of the Mozilla Public\n# License, v. 2.0. If a copy of the MPL was not distributed with this\n# file, You can obtain one at http://mozilla.org/MPL/2.0/.\n\n# LOCALIZATION NOTE These strings are used inside the Debugger\n# which is available from the Web Developer sub-menu -> 'Debugger'.\n# The correct localization of this file might be to keep it in\n# English, or another language commonly spoken among web developers.\n# You want to make that choice consistent across the developer tools.\n# A good criteria is the language in which you'd find the best\n# documentation on web development on the web.\n\n# LOCALIZATION NOTE (collapsePanes): This is the tooltip for the button\n# that collapses the left and right panes in the debugger UI.\ncollapsePanes=Collapse panes\n\n# LOCALIZATION NOTE (copySource): This is the text that appears in the\n# context menu to copy the selected source of file open.\ncopySource=Copy\ncopySource.accesskey=y\n\n# LOCALIZATION NOTE (copySourceUri2): This is the text that appears in the\n# context menu to copy the source URI of file open.\ncopySourceUri2=Copy source URI\ncopySourceUri2.accesskey=u\n\n# LOCALIZATION NOTE (copyFunction): This is the text that appears in the\n# context menu to copy the function the user selected\ncopyFunction.label=Copy function\ncopyFunction.accesskey=F\n\n# LOCALIZATION NOTE (copyStackTrace): This is the text that appears in the\n# context menu to copy the stack trace methods, file names and row number.\ncopyStackTrace=Copy stack trace\ncopyStackTrace.accesskey=c\n\n# LOCALIZATION NOTE (expandPanes): This is the tooltip for the button\n# that expands the left and right panes in the debugger UI.\nexpandPanes=Expand panes\n\n# LOCALIZATION NOTE (pauseButtonTooltip): The tooltip that is displayed for the pause\n# button when the debugger is in a running state.\npauseButtonTooltip=Pause %S\n\n# LOCALIZATION NOTE (pausePendingButtonTooltip): The tooltip that is displayed for\n# the pause button after it's been clicked but before the next JavaScript to run.\npausePendingButtonTooltip=Waiting for next execution\n\n# LOCALIZATION NOTE (resumeButtonTooltip): The label that is displayed on the pause\n# button when the debugger is in a paused state.\nresumeButtonTooltip=Resume %S\n\n# LOCALIZATION NOTE (stepOverTooltip): The label that is displayed on the\n# button that steps over a function call.\nstepOverTooltip=Step over %S\n\n# LOCALIZATION NOTE (stepInTooltip): The label that is displayed on the\n# button that steps into a function call.\nstepInTooltip=Step in %S\n\n# LOCALIZATION NOTE (stepOutTooltip): The label that is displayed on the\n# button that steps out of a function call.\nstepOutTooltip=Step out %S\n\n# LOCALIZATION NOTE (workersHeader): The text to display in the events\n# header.\nworkersHeader=Workers\n\n# LOCALIZATION NOTE (noWorkersText): The text to display in the workers list\n# when there are no workers.\nnoWorkersText=This page has no workers.\n\n# LOCALIZATION NOTE (noSourcesText): The text to display in the sources list\n# when there are no sources.\nnoSourcesText=This page has no sources.\n\n# LOCALIZATION NOTE (noEventListenersText): The text to display in the events tab\n# when there are no events.\nnoEventListenersText=No event listeners to display.\n\n# LOCALIZATION NOTE (eventListenersHeader): The text to display in the events\n# header.\neventListenersHeader=Event listeners\n\n# LOCALIZATION NOTE (noStackFramesText): The text to display in the call stack tab\n# when there are no stack frames.\nnoStackFramesText=No stack frames to display\n\n# LOCALIZATION NOTE (eventCheckboxTooltip): The tooltip text to display when\n# the user hovers over the checkbox used to toggle an event breakpoint.\neventCheckboxTooltip=Toggle breaking on this event\n\n# LOCALIZATION NOTE (eventOnSelector): The text to display in the events tab\n# for every event item, between the event type and event selector.\neventOnSelector=on\n\n# LOCALIZATION NOTE (eventInSource): The text to display in the events tab\n# for every event item, between the event selector and listener's owner source.\neventInSource=in\n\n# LOCALIZATION NOTE (eventNodes): The text to display in the events tab when\n# an event is listened on more than one target node.\neventNodes=%S nodes\n\n# LOCALIZATION NOTE (eventNative): The text to display in the events tab when\n# a listener is added from plugins, thus getting translated to native code.\neventNative=[native code]\n\n# LOCALIZATION NOTE (*Events): The text to display in the events tab for\n# each group of sub-level event entries.\nanimationEvents=Animation\naudioEvents=Audio\nbatteryEvents=Battery\nclipboardEvents=Clipboard\ncompositionEvents=Composition\ndeviceEvents=Device\ndisplayEvents=Display\ndragAndDropEvents=Drag and Drop\ngamepadEvents=Gamepad\nindexedDBEvents=IndexedDB\ninteractionEvents=Interaction\nkeyboardEvents=Keyboard\nmediaEvents=HTML5 Media\nmouseEvents=Mouse\nmutationEvents=Mutation\nnavigationEvents=Navigation\npointerLockEvents=Pointer Lock\nsensorEvents=Sensor\nstorageEvents=Storage\ntimeEvents=Time\ntouchEvents=Touch\notherEvents=Other\n\n# LOCALIZATION NOTE (blackboxCheckboxTooltip2): The tooltip text to display when\n# the user hovers over the checkbox used to toggle blackboxing its associated\n# source.\nblackboxCheckboxTooltip2=Toggle blackboxing\n\n# LOCALIZATION NOTE (sources.search.key2): Key shortcut to open the search for\n# searching all the source files the debugger has seen.\nsources.search.key2=CmdOrCtrl+P\n\n# LOCALIZATION NOTE (sources.search.alt.key): A second key shortcut to open the\n# search for searching all the source files the debugger has seen.\nsources.search.alt.key=CmdOrCtrl+O\n\n# LOCALIZATION NOTE (projectTextSearch.key): A key shortcut to open the\n# full project text search for searching all the files the debugger has seen.\nprojectTextSearch.key=CmdOrCtrl+Shift+F\n\n# LOCALIZATION NOTE (functionSearch.key): A key shortcut to open the\n# modal for searching functions in a file.\nfunctionSearch.key=CmdOrCtrl+Shift+O\n\n# LOCALIZATION NOTE (toggleBreakpoint.key): A key shortcut to toggle\n# breakpoints.\ntoggleBreakpoint.key=CmdOrCtrl+B\n\n# LOCALIZATION NOTE (toggleCondPanel.key): A key shortcut to toggle\n# the conditional breakpoint panel.\ntoggleCondPanel.key=CmdOrCtrl+Shift+B\n\n# LOCALIZATION NOTE (stepOut.key): A key shortcut to\n# step out.\nstepOut.key=Shift+F11\n\n# LOCALIZATION NOTE (shortcuts.header.editor): Sections header in\n# the shortcuts modal for keyboard shortcuts related to editing.\nshortcuts.header.editor=Editor\n\n# LOCALIZATION NOTE (shortcuts.header.stepping): Sections header in\n# the shortcuts modal for keyboard shortcuts related to stepping.\nshortcuts.header.stepping=Stepping\n\n# LOCALIZATION NOTE (shortcuts.header.search): Sections header in\n# the shortcuts modal for keyboard shortcuts related to search.\nshortcuts.header.search=Search\n\n# LOCALIZATION NOTE (projectTextSearch.placeholder): A placeholder shown\n# when searching across all of the files in a project.\nprojectTextSearch.placeholder=Find in files…\n\n# LOCALIZATION NOTE (projectTextSearch.noResults): The center pane Text Search\n# message when the query did not match any text of all files in a project.\nprojectTextSearch.noResults=No results found\n\n# LOCALIZATION NOTE (sources.noSourcesAvailable): Text shown when the debugger\n# does not have any sources.\nsources.noSourcesAvailable=This page has no sources\n\n# LOCALIZATION NOTE (sourceSearch.search.key2): Key shortcut to open the search\n# for searching within a the currently opened files in the editor\nsourceSearch.search.key2=CmdOrCtrl+F\n\n# LOCALIZATION NOTE (sourceSearch.search.placeholder): placeholder text in\n# the source search input bar\nsourceSearch.search.placeholder=Search in file…\n\n# LOCALIZATION NOTE (sourceSearch.search.again.key2): Key shortcut to highlight\n# the next occurrence of the last search triggered from a source search\nsourceSearch.search.again.key2=CmdOrCtrl+G\n\n# LOCALIZATION NOTE (sourceSearch.search.againPrev.key2): Key shortcut to highlight\n# the previous occurrence of the last search triggered from a source search\nsourceSearch.search.againPrev.key2=CmdOrCtrl+Shift+G\n\n# LOCALIZATION NOTE (sourceSearch.resultsSummary1): Shows a summary of\n# the number of matches for autocomplete\nsourceSearch.resultsSummary1=%d results\n\n# LOCALIZATION NOTE (noMatchingStringsText): The text to display in the\n# global search results when there are no matching strings after filtering.\nnoMatchingStringsText=No matches found\n\n# LOCALIZATION NOTE (emptySearchText): This is the text that appears in the\n# filter text box when it is empty and the scripts container is selected.\nemptySearchText=Search scripts (%S)\n\n# LOCALIZATION NOTE (emptyVariablesFilterText): This is the text that\n# appears in the filter text box for the variables view container.\nemptyVariablesFilterText=Filter variables\n\n# LOCALIZATION NOTE (emptyPropertiesFilterText): This is the text that\n# appears in the filter text box for the editor's variables view bubble.\nemptyPropertiesFilterText=Filter properties\n\n# LOCALIZATION NOTE (searchPanelFilter): This is the text that appears in the\n# filter panel popup for the filter scripts operation.\nsearchPanelFilter=Filter scripts (%S)\n\n# LOCALIZATION NOTE (searchPanelGlobal): This is the text that appears in the\n# filter panel popup for the global search operation.\nsearchPanelGlobal=Search in all files (%S)\n\n# LOCALIZATION NOTE (searchPanelFunction): This is the text that appears in the\n# filter panel popup for the function search operation.\nsearchPanelFunction=Search for function definition (%S)\n\n# LOCALIZATION NOTE (searchPanelToken): This is the text that appears in the\n# filter panel popup for the token search operation.\nsearchPanelToken=Find in this file (%S)\n\n# LOCALIZATION NOTE (searchPanelGoToLine): This is the text that appears in the\n# filter panel popup for the line search operation.\nsearchPanelGoToLine=Go to line (%S)\n\n# LOCALIZATION NOTE (searchPanelVariable): This is the text that appears in the\n# filter panel popup for the variables search operation.\nsearchPanelVariable=Filter variables (%S)\n\n# LOCALIZATION NOTE (breakpointMenuItem): The text for all the elements that\n# are displayed in the breakpoints menu item popup.\nbreakpointMenuItem.setConditional=Configure conditional breakpoint\nbreakpointMenuItem.enableSelf2.label=Enable\nbreakpointMenuItem.enableSelf2.accesskey=E\nbreakpointMenuItem.disableSelf2.label=Disable\nbreakpointMenuItem.disableSelf2.accesskey=D\nbreakpointMenuItem.deleteSelf2.label=Remove\nbreakpointMenuItem.deleteSelf2.accesskey=R\nbreakpointMenuItem.enableOthers2.label=Enable others\nbreakpointMenuItem.enableOthers2.accesskey=o\nbreakpointMenuItem.disableOthers2.label=Disable others\nbreakpointMenuItem.disableOthers2.accesskey=s\nbreakpointMenuItem.deleteOthers2.label=Remove others\nbreakpointMenuItem.deleteOthers2.accesskey=h\nbreakpointMenuItem.enableAll2.label=Enable all\nbreakpointMenuItem.enableAll2.accesskey=b\nbreakpointMenuItem.disableAll2.label=Disable all\nbreakpointMenuItem.disableAll2.accesskey=k\nbreakpointMenuItem.deleteAll2.label=Remove all\nbreakpointMenuItem.deleteAll2.accesskey=a\nbreakpointMenuItem.removeCondition2.label=Remove condition\nbreakpointMenuItem.removeCondition2.accesskey=c\nbreakpointMenuItem.addCondition2.label=Add condition\nbreakpointMenuItem.addCondition2.accesskey=A\nbreakpointMenuItem.editCondition2.label=Edit condition\nbreakpointMenuItem.editCondition2.accesskey=n\nbreakpointMenuItem.enableSelf=Enable breakpoint\nbreakpointMenuItem.enableSelf.accesskey=E\nbreakpointMenuItem.disableSelf=Disable breakpoint\nbreakpointMenuItem.disableSelf.accesskey=D\nbreakpointMenuItem.deleteSelf=Remove breakpoint\nbreakpointMenuItem.deleteSelf.accesskey=R\nbreakpointMenuItem.enableOthers=Enable others\nbreakpointMenuItem.enableOthers.accesskey=o\nbreakpointMenuItem.disableOthers=Disable others\nbreakpointMenuItem.disableOthers.accesskey=s\nbreakpointMenuItem.deleteOthers=Remove others\nbreakpointMenuItem.deleteOthers.accesskey=h\nbreakpointMenuItem.enableAll=Enable all breakpoints\nbreakpointMenuItem.enableAll.accesskey=b\nbreakpointMenuItem.disableAll=Disable all breakpoints\nbreakpointMenuItem.disableAll.accesskey=k\nbreakpointMenuItem.deleteAll=Remove all breakpoints\nbreakpointMenuItem.deleteAll.accesskey=a\nbreakpointMenuItem.removeCondition.label=Remove breakpoint condition\nbreakpointMenuItem.removeCondition.accesskey=c\nbreakpointMenuItem.editCondition.label=Edit breakpoint condition\nbreakpointMenuItem.editCondition.accesskey=n\n\n# LOCALIZATION NOTE (breakpoints.header): Breakpoints right sidebar pane header.\nbreakpoints.header=Breakpoints\n\n# LOCALIZATION NOTE (breakpoints.none): The text that appears when there are\n# no breakpoints present\nbreakpoints.none=No breakpoints\n\n# LOCALIZATION NOTE (breakpoints.enable): The text that may appear as a tooltip\n# when hovering over the 'disable breakpoints' switch button in right sidebar\nbreakpoints.enable=Enable breakpoints\n\n# LOCALIZATION NOTE (breakpoints.disable): The text that may appear as a tooltip\n# when hovering over the 'disable breakpoints' switch button in right sidebar\nbreakpoints.disable=Disable breakpoints\n\n# LOCALIZATION NOTE (breakpoints.removeBreakpointTooltip): The tooltip that is displayed\n# for remove breakpoint button in right sidebar\nbreakpoints.removeBreakpointTooltip=Remove breakpoint\n\n# LOCALIZATION NOTE (callStack.header): Call Stack right sidebar pane header.\ncallStack.header=Call stack\n\n# LOCALIZATION NOTE (callStack.notPaused): Call Stack right sidebar pane\n# message when not paused.\ncallStack.notPaused=Not paused\n\n# LOCALIZATION NOTE (callStack.collapse): Call Stack right sidebar pane\n# message to hide some of the frames that are shown.\ncallStack.collapse=Collapse rows\n\n# LOCALIZATION NOTE (callStack.expand): Call Stack right sidebar pane\n# message to show more of the frames.\ncallStack.expand=Expand rows\n\n# LOCALIZATION NOTE (editor.searchResults): Editor Search bar message\n# for the summarizing the selected search result. e.g. 5 of 10 results.\neditor.searchResults=%d of %d results\n\n# LOCALIZATION NOTE (sourceSearch.singleResult): Copy shown when there is one result.\neditor.singleResult=1 result\n\n# LOCALIZATION NOTE (editor.noResults): Editor Search bar message\n# for when no results found.\neditor.noResults=No results\n\n# LOCALIZATION NOTE (editor.searchResults.nextResult): Editor Search bar\n# tooltip for traversing to the Next Result\neditor.searchResults.nextResult=Next result\n\n# LOCALIZATION NOTE (editor.searchResults.prevResult): Editor Search bar\n# tooltip for traversing to the Previous Result\neditor.searchResults.prevResult=Previous result\n\n# LOCALIZATION NOTE (editor.searchTypeToggleTitle): Search bar title for\n# toggling search type buttons(function search, variable search)\neditor.searchTypeToggleTitle=Search for:\n\n# LOCALIZATION NOTE (editor.continueToHere.label): Editor gutter context\n# menu item for jumping to a new paused location\neditor.continueToHere.label=Continue to here\neditor.continueToHere.accesskey=H\n\n# LOCALIZATION NOTE (editor.addBreakpoint): Editor gutter context menu item\n# for adding a breakpoint on a line.\neditor.addBreakpoint=Add breakpoint\n\n# LOCALIZATION NOTE (editor.disableBreakpoint): Editor gutter context menu item\n# for disabling a breakpoint on a line.\neditor.disableBreakpoint=Disable breakpoint\n\n# LOCALIZATION NOTE (editor.enableBreakpoint): Editor gutter context menu item\n# for enabling a breakpoint on a line.\neditor.enableBreakpoint=Enable breakpoint\n\n# LOCALIZATION NOTE (editor.removeBreakpoint): Editor gutter context menu item\n# for removing a breakpoint on a line.\neditor.removeBreakpoint=Remove breakpoint\n\n# LOCALIZATION NOTE (editor.editBreakpoint): Editor gutter context menu item\n# for setting a breakpoint condition on a line.\neditor.editBreakpoint=Edit breakpoint\n\n# LOCALIZATION NOTE (editor.addConditionalBreakpoint): Editor gutter context\n# menu item for adding a breakpoint condition on a line.\neditor.addConditionalBreakpoint=Add conditional breakpoint\n\n# LOCALIZATION NOTE (editor.conditionalPanel.placeholder): Placeholder text for\n# input element inside ConditionalPanel component\neditor.conditionalPanel.placeholder=This breakpoint will pause when the expression is true\n\n# LOCALIZATION NOTE (editor.conditionalPanel.placeholder): Tooltip text for\n# close button inside ConditionalPanel component\neditor.conditionalPanel.close=Cancel edit breakpoint and close\n\n# LOCALIZATION NOTE (editor.jumpToMappedLocation1): Context menu item\n# for navigating to a source mapped location\neditor.jumpToMappedLocation1=Jump to %S location\n\n# LOCALIZATION NOTE (framework.disableGrouping): This is the text that appears in the\n# context menu to disable framework grouping.\nframework.disableGrouping=Disable framework grouping\nframework.disableGrouping.accesskey=u\n\n# LOCALIZATION NOTE (framework.enableGrouping): This is the text that appears in the\n# context menu to enable framework grouping.\nframework.enableGrouping=Enable framework grouping\nframework.enableGrouping.accesskey=u\n\n# LOCALIZATION NOTE (generated): Source Map term for a server source location\ngenerated=Generated\n\n# LOCALIZATION NOTE (original): Source Map term for a debugger UI source location\noriginal=original\n\n# LOCALIZATION NOTE (expressions.placeholder): Placeholder text for expression\n# input element\nexpressions.placeholder=Add watch expression\n\n# LOCALIZATION NOTE (sourceTabs.closeTab): Editor source tab context menu item\n# for closing the selected tab below the mouse.\nsourceTabs.closeTab=Close tab\nsourceTabs.closeTab.accesskey=c\n\n# LOCALIZATION NOTE (sourceTabs.closeOtherTabs): Editor source tab context menu item\n# for closing the other tabs.\nsourceTabs.closeOtherTabs=Close other tabs\nsourceTabs.closeOtherTabs.accesskey=o\n\n# LOCALIZATION NOTE (sourceTabs.closeTabsToEnd): Editor source tab context menu item\n# for closing the tabs to the end (the right for LTR languages) of the selected tab.\nsourceTabs.closeTabsToEnd=Close tabs to the right\nsourceTabs.closeTabsToEnd.accesskey=e\n\n# LOCALIZATION NOTE (sourceTabs.closeAllTabs): Editor source tab context menu item\n# for closing all tabs.\nsourceTabs.closeAllTabs=Close all tabs\nsourceTabs.closeAllTabs.accesskey=a\n\n# LOCALIZATION NOTE (sourceTabs.revealInTree): Editor source tab context menu item\n# for revealing source in tree.\nsourceTabs.revealInTree=Reveal in tree\nsourceTabs.revealInTree.accesskey=r\n\n# LOCALIZATION NOTE (sourceTabs.prettyPrint): Editor source tab context menu item\n# for pretty printing the source.\nsourceTabs.prettyPrint=Pretty print source\nsourceTabs.prettyPrint.accesskey=p\n\n# LOCALIZATION NOTE (sourceFooter.blackbox): Tooltip text associated\n# with the blackbox button\nsourceFooter.blackbox=Blackbox source\nsourceFooter.blackbox.accesskey=B\n\n# LOCALIZATION NOTE (sourceFooter.unblackbox): Tooltip text associated\n# with the blackbox button\nsourceFooter.unblackbox=Unblackbox source\nsourceFooter.unblackbox.accesskey=b\n\n# LOCALIZATION NOTE (sourceFooter.blackboxed): Text associated\n# with a blackboxed source\nsourceFooter.blackboxed=Blackboxed source\n\n# LOCALIZATION NOTE (sourceFooter.codeCoverage): Text associated\n# with a code coverage button\nsourceFooter.codeCoverage=Code coverage\n\n# LOCALIZATION NOTE (sourceTabs.closeTabButtonTooltip): The tooltip that is displayed\n# for close tab button in source tabs.\nsourceTabs.closeTabButtonTooltip=Close tab\n\n# LOCALIZATION NOTE (sourceTabs.newTabButtonTooltip): The tooltip that is displayed for\n# new tab button in source tabs.\nsourceTabs.newTabButtonTooltip=Search for sources (%S)\n\n# LOCALIZATION NOTE (scopes.header): Scopes right sidebar pane header.\nscopes.header=Scopes\n\n# LOCALIZATION NOTE (scopes.notAvailable): Scopes right sidebar pane message\n# for when the debugger is paused, but there isn't pause data.\nscopes.notAvailable=Scopes unavailable\n\n# LOCALIZATION NOTE (scopes.notPaused): Scopes right sidebar pane message\n# for when the debugger is not paused.\nscopes.notPaused=Not paused\n\n# LOCALIZATION NOTE (scopes.block): Refers to a block of code in\n# the scopes pane when the debugger is paused.\nscopes.block=Block\n\n# LOCALIZATION NOTE (sources.header): Sources left sidebar header\nsources.header=Sources\n\n# LOCALIZATION NOTE (outline.header): Outline left sidebar header\noutline.header=Outline\n\n# LOCALIZATION NOTE (outline.noFunctions): Outline text when there are no functions to display\noutline.noFunctions=No functions\n\n# LOCALIZATION NOTE (sources.search): Sources left sidebar prompt\n# e.g. Cmd+P to search. On a mac, we use the command unicode character.\n# On windows, it's ctrl.\nsources.search=%S to search\n\n# LOCALIZATION NOTE (watchExpressions.header): Watch Expressions right sidebar\n# pane header.\nwatchExpressions.header=Watch expressions\n\n# LOCALIZATION NOTE (watchExpressions.refreshButton): Watch Expressions header\n# button for refreshing the expressions.\nwatchExpressions.refreshButton=Refresh\n\n# LOCALIZATION NOTE (welcome.search): The center pane welcome panel's\n# search prompt. e.g. cmd+p to search for files. On windows, it's ctrl, on\n# a mac we use the unicode character.\nwelcome.search=%S to search for sources\n\n# LOCALIZATION NOTE (welcome.findInFiles): The center pane welcome panel's\n# search prompt. e.g. cmd+f to search for files. On windows, it's ctrl+shift+f, on\n# a mac we use the unicode character.\nwelcome.findInFiles=%S to find in files\n\n# LOCALIZATION NOTE (welcome.searchFunction): Label displayed in the welcome\n# panel. %S is replaced by the keyboard shortcut to search for functions.\nwelcome.searchFunction=%S to search for functions in file\n\n# LOCALIZATION NOTE (sourceSearch.search): The center pane Source Search\n# prompt for searching for files.\nsourceSearch.search=Search sources…\n\n# LOCALIZATION NOTE (sourceSearch.noResults): The center pane Source Search\n# message when the query did not match any of the sources.\nsourceSearch.noResults2=No results found\n\n# LOCALIZATION NOTE (ignoreExceptions): The pause on exceptions button tooltip\n# when the debugger will not pause on exceptions.\nignoreExceptions=Ignore exceptions. Click to pause on uncaught exceptions\n\n# LOCALIZATION NOTE (pauseOnUncaughtExceptions): The pause on exceptions button\n# tooltip when the debugger will pause on uncaught exceptions.\npauseOnUncaughtExceptions=Pause on uncaught exceptions. Click to pause on all exceptions\n\n# LOCALIZATION NOTE (pauseOnExceptions): The pause on exceptions button tooltip\n# when the debugger will pause on all exceptions.\npauseOnExceptions=Pause on all exceptions. Click to ignore exceptions\n\n# LOCALIZATION NOTE (loadingText): The text that is displayed in the script\n# editor when the loading process has started but there is no file to display\n# yet.\nloadingText=Loading\\u2026\n\n# LOCALIZATION NOTE (errorLoadingText3): The text that is displayed in the debugger\n# viewer when there is an error loading a file\nerrorLoadingText3=Error loading this URI: %S\n\n# LOCALIZATION NOTE (addWatchExpressionText): The text that is displayed in the\n# watch expressions list to add a new item.\naddWatchExpressionText=Add watch expression\n\n# LOCALIZATION NOTE (addWatchExpressionButton): The button that is displayed in the\n# variables view popup.\naddWatchExpressionButton=Watch\n\n# LOCALIZATION NOTE (emptyVariablesText): The text that is displayed in the\n# variables pane when there are no variables to display.\nemptyVariablesText=No variables to display\n\n# LOCALIZATION NOTE (scopeLabel): The text that is displayed in the variables\n# pane as a header for each variable scope (e.g. \"Global scope, \"With scope\",\n# etc.).\nscopeLabel=%S scope\n\n# LOCALIZATION NOTE (watchExpressionsScopeLabel): The name of the watch\n# expressions scope. This text is displayed in the variables pane as a header for\n# the watch expressions scope.\nwatchExpressionsScopeLabel=Watch expressions\n\n# LOCALIZATION NOTE (globalScopeLabel): The name of the global scope. This text\n# is added to scopeLabel and displayed in the variables pane as a header for\n# the global scope.\nglobalScopeLabel=Global\n\n# LOCALIZATION NOTE (variablesViewErrorStacktrace): This is the text that is\n# shown before the stack trace in an error.\nvariablesViewErrorStacktrace=Stack trace:\n\n# LOCALIZATION NOTE (variablesViewMoreObjects): the text that is displayed\n# when you have an object preview that does not show all of the elements. At the end of the list\n# you see \"N more...\" in the web console output.\n# This is a semi-colon list of plural forms.\n# See: http://developer.mozilla.org/en/docs/Localization_and_Plurals\n# #1 number of remaining items in the object\n# example: 3 more…\nvariablesViewMoreObjects=#1 more…;#1 more…\n\n# LOCALIZATION NOTE (variablesEditableNameTooltip): The text that is displayed\n# in the variables list on an item with an editable name.\nvariablesEditableNameTooltip=Double click to edit\n\n# LOCALIZATION NOTE (variablesEditableValueTooltip): The text that is displayed\n# in the variables list on an item with an editable value.\nvariablesEditableValueTooltip=Click to change value\n\n# LOCALIZATION NOTE (variablesCloseButtonTooltip): The text that is displayed\n# in the variables list on an item which can be removed.\nvariablesCloseButtonTooltip=Click to remove\n\n# LOCALIZATION NOTE (variablesEditButtonTooltip): The text that is displayed\n# in the variables list on a getter or setter which can be edited.\nvariablesEditButtonTooltip=Click to set value\n\n# LOCALIZATION NOTE (variablesEditableValueTooltip): The text that is displayed\n# in a tooltip on the \"open in inspector\" button in the the variables list for a\n# DOMNode item.\nvariablesDomNodeValueTooltip=Click to select the node in the inspector\n\n# LOCALIZATION NOTE (configurable|...|Tooltip): The text that is displayed\n# in the variables list on certain variables or properties as tooltips.\n# Expanations of what these represent can be found at the following links:\n# https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty\n# https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object/isExtensible\n# https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object/isFrozen\n# https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object/isSealed\n# It's probably best to keep these in English.\nconfigurableTooltip=configurable\nenumerableTooltip=enumerable\nwritableTooltip=writable\nfrozenTooltip=frozen\nsealedTooltip=sealed\nextensibleTooltip=extensible\noverriddenTooltip=overridden\nWebIDLTooltip=WebIDL\n\n# LOCALIZATION NOTE (variablesSeparatorLabel): The text that is displayed\n# in the variables list as a separator between the name and value.\nvariablesSeparatorLabel=:\n\n# LOCALIZATION NOTE (watchExpressionsSeparatorLabel2): The text that is displayed\n# in the watch expressions list as a separator between the code and evaluation.\nwatchExpressionsSeparatorLabel2=\\u0020→\n\n# LOCALIZATION NOTE (functionSearchSeparatorLabel): The text that is displayed\n# in the functions search panel as a separator between function's inferred name\n# and its real name (if available).\nfunctionSearchSeparatorLabel=←\n\n# LOCALIZATION NOTE(gotoLineModal.placeholder): The placeholder\n# text displayed when the user searches for specific lines in a file\ngotoLineModal.placeholder=Go to line…\ngotoLineModal.key=CmdOrCtrl+Shift+;\n\n# LOCALIZATION NOTE(symbolSearch.search.functionsPlaceholder): The placeholder\n# text displayed when the user searches for functions in a file\nsymbolSearch.search.functionsPlaceholder=Search functions…\n\n# LOCALIZATION NOTE(symbolSearch.search.variablesPlaceholder): The placeholder\n# text displayed when the user searches for variables in a file\nsymbolSearch.search.variablesPlaceholder=Search variables…\n\n# LOCALIZATION NOTE(symbolSearch.search.key2): The Key Shortcut for\n# searching for a function or variable\nsymbolSearch.search.key2=CmdOrCtrl+Shift+O\n\n# LOCALIZATION NOTE(symbolSearch.searchModifier.modifiersLabel): A label\n# preceding the group of modifiers\nsymbolSearch.searchModifier.modifiersLabel=Modifiers:\n\n# LOCALIZATION NOTE(symbolSearch.searchModifier.regex): A search option\n# when searching text in a file\nsymbolSearch.searchModifier.regex=Regex\n\n# LOCALIZATION NOTE(symbolSearch.searchModifier.caseSensitive): A search option\n# when searching text in a file\nsymbolSearch.searchModifier.caseSensitive=Case sensitive\n\n# LOCALIZATION NOTE(symbolSearch.searchModifier.wholeWord): A search option\n# when searching text in a file\nsymbolSearch.searchModifier.wholeWord=Whole word\n\n# LOCALIZATION NOTE (resumptionOrderPanelTitle): This is the text that appears\n# as a description in the notification panel popup, when multiple debuggers are\n# open in separate tabs and the user tries to resume them in the wrong order.\n# The substitution parameter is the URL of the last paused window that must be\n# resumed first.\nresumptionOrderPanelTitle=There are one or more paused debuggers. Please resume the most-recently paused debugger first at: %S\n\nvariablesViewOptimizedOut=(optimized away)\nvariablesViewUninitialized=(uninitialized)\nvariablesViewMissingArgs=(unavailable)\n\nanonymousSourcesLabel=Anonymous sources\n\nexperimental=This is an experimental feature\n\n# LOCALIZATION NOTE (whyPaused.debuggerStatement): The text that is displayed\n# in a info block explaining how the debugger is currently paused due to a `debugger`\n# statement in the code\nwhyPaused.debuggerStatement=Paused on debugger statement\n\n# LOCALIZATION NOTE (whyPaused.breakpoint): The text that is displayed\n# in a info block explaining how the debugger is currently paused on a breakpoint\nwhyPaused.breakpoint=Paused on breakpoint\n\n# LOCALIZATION NOTE (whyPaused.exception): The text that is displayed\n# in a info block explaining how the debugger is currently paused on an exception\nwhyPaused.exception=Paused on exception\n\n# LOCALIZATION NOTE (whyPaused.resumeLimit): The text that is displayed\n# in a info block explaining how the debugger is currently paused while stepping\n# in or out of the stack\nwhyPaused.resumeLimit=Paused while stepping\n\n# LOCALIZATION NOTE (whyPaused.pauseOnDOMEvents): The text that is displayed\n# in a info block explaining how the debugger is currently paused on a\n# dom event\nwhyPaused.pauseOnDOMEvents=Paused on event listener\n\n# LOCALIZATION NOTE (whyPaused.breakpointConditionThrown): The text that is displayed\n# in an info block when evaluating a conditional breakpoint throws an error\nwhyPaused.breakpointConditionThrown=Error with conditional breakpoint\n\n# LOCALIZATION NOTE (whyPaused.xhr): The text that is displayed\n# in a info block explaining how the debugger is currently paused on an\n# xml http request\nwhyPaused.xhr=Paused on XMLHttpRequest\n\n# LOCALIZATION NOTE (whyPaused.promiseRejection): The text that is displayed\n# in a info block explaining how the debugger is currently paused on a\n# promise rejection\nwhyPaused.promiseRejection=Paused on promise rejection\n\n# LOCALIZATION NOTE (whyPaused.assert): The text that is displayed\n# in a info block explaining how the debugger is currently paused on an\n# assert\nwhyPaused.assert=Paused on assertion\n\n# LOCALIZATION NOTE (whyPaused.debugCommand): The text that is displayed\n# in a info block explaining how the debugger is currently paused on a\n# debugger statement\nwhyPaused.debugCommand=Paused on debugged function\n\n# LOCALIZATION NOTE (whyPaused.other): The text that is displayed\n# in a info block explaining how the debugger is currently paused on an event\n# listener breakpoint set\nwhyPaused.other=Debugger paused\n\n# LOCALIZATION NOTE (ctrl): The text that is used for documenting\n# keyboard shortcuts that use the control key\nctrl=Ctrl\n\n# LOCALIZATION NOTE (anonymous): The text that is displayed when the\n# display name is null.\nanonymous=(anonymous)\n\n# LOCALIZATION NOTE (shortcuts.toggleBreakpoint): text describing\n# keyboard shortcut action for toggling breakpoint\nshortcuts.toggleBreakpoint=Toggle Breakpoint\n\n# LOCALIZATION NOTE (shortcuts.toggleCondPanel): text describing\n# keyboard shortcut action for toggling conditional panel keyboard\nshortcuts.toggleCondPanel=Toggle Conditional Panel\n\n# LOCALIZATION NOTE (shortcuts.pauseOrResume): text describing\n# keyboard shortcut action for pause of resume\nshortcuts.pauseOrResume=Pause/Resume\n\n# LOCALIZATION NOTE (shortcuts.stepOver): text describing\n# keyboard shortcut action for stepping over\nshortcuts.stepOver=Step Over\n\n# LOCALIZATION NOTE (shortcuts.stepIn): text describing\n# keyboard shortcut action for stepping in\nshortcuts.stepIn=Step In\n\n# LOCALIZATION NOTE (shortcuts.stepOut): text describing\n# keyboard shortcut action for stepping out\nshortcuts.stepOut=Step Out\n\n# LOCALIZATION NOTE (shortcuts.fileSearch): text describing\n# keyboard shortcut action for source file search\nshortcuts.fileSearch=Source File Search\n\n# LOCALIZATION NOTE (shortcuts.searchAgain): text describing\n# keyboard shortcut action for searching again\nshortcuts.searchAgain=Search Again\n\n# LOCALIZATION NOTE (shortcuts.projectSearch): text describing\n# keyboard shortcut action for full project search\nshortcuts.projectSearch=Full Project Search\n\n# LOCALIZATION NOTE (shortcuts.functionSearch): text describing\n# keyboard shortcut action for function search\nshortcuts.functionSearch=Function Search\n\n# LOCALIZATION NOTE (shortcuts.buttonName): text describing\n# keyboard shortcut button text\nshortcuts.buttonName=Keyboard shortcuts\n"
 
 /***/ }),
 /* 961 */,
 /* 962 */,
 /* 963 */,
 /* 964 */,
 /* 965 */
 /***/ (function(module, exports) {
@@ -38423,17 +38478,17 @@ var _actions = __webpack_require__(244);
 var _actions2 = _interopRequireDefault(_actions);
 
 var _frame = __webpack_require__(1014);
 
 var _clipboard = __webpack_require__(423);
 
 var _selectors = __webpack_require__(242);
 
-__webpack_require__(1263);
+__webpack_require__(1338);
 
 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
 
 var NUM_FRAMES_SHOWN = 7;
 
 class Frames extends _react.Component {
 
   constructor() {
@@ -39116,17 +39171,17 @@ var _Svg = __webpack_require__(344);
 var _Svg2 = _interopRequireDefault(_Svg);
 
 var _frame = __webpack_require__(1014);
 
 var _FrameMenu = __webpack_require__(1032);
 
 var _FrameMenu2 = _interopRequireDefault(_FrameMenu);
 
-__webpack_require__(1261);
+__webpack_require__(1336);
 
 var _Frame = __webpack_require__(1013);
 
 var _Frame2 = _interopRequireDefault(_Frame);
 
 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
 
 function FrameLocation(_ref) {
@@ -39364,17 +39419,17 @@ Object.defineProperty(exports, "__esModu
 var _react = __webpack_require__(0);
 
 var _react2 = _interopRequireDefault(_react);
 
 var _classnames = __webpack_require__(175);
 
 var _classnames2 = _interopRequireDefault(_classnames);
 
-__webpack_require__(1252);
+__webpack_require__(1326);
 
 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
 
 var BracketArrow = (_ref) => {
   var orientation = _ref.orientation,
       left = _ref.left,
       top = _ref.top,
       bottom = _ref.bottom;
@@ -40126,17 +40181,17 @@ var _Svg2 = _interopRequireDefault(_Svg)
 var _ManagedTree = __webpack_require__(419);
 
 var _ManagedTree2 = _interopRequireDefault(_ManagedTree);
 
 var _SearchInput = __webpack_require__(377);
 
 var _SearchInput2 = _interopRequireDefault(_SearchInput);
 
-__webpack_require__(1238);
+__webpack_require__(1314);
 
 var _sourcesTree = __webpack_require__(39);
 
 var _highlight = __webpack_require__(1184);
 
 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
 
 class TextSearch extends _react.Component {
@@ -40437,17 +40492,17 @@ exports.default = renderWhyPaused;
 var _react = __webpack_require__(0);
 
 var _react2 = _interopRequireDefault(_react);
 
 var _lodash = __webpack_require__(2);
 
 var _pause = __webpack_require__(255);
 
-__webpack_require__(1262);
+__webpack_require__(1337);
 
 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
 
 function renderExceptionSummary(exception) {
   if ((0, _lodash.isString)(exception)) {
     return exception;
   }
 
@@ -40604,17 +40659,17 @@ var _require = __webpack_require__(830),
     Menu = _require.Menu,
     MenuItem = _require.MenuItem;
 
 function inToolbox() {
   return window.parent.document.documentURI == "about:devtools-toolbox";
 }
 
 if (!inToolbox()) {
-  __webpack_require__(1224);
+  __webpack_require__(1301);
 }
 
 function createPopup(doc) {
   var popup = doc.createElement("menupopup");
   popup.className = "landing-popup";
   if (popup.openPopupAtScreen) {
     return popup;
   }
@@ -41318,17 +41373,17 @@ var _SourceSearch2 = _interopRequireDefa
 var _ToggleSearch = __webpack_require__(284);
 
 var _ToggleSearch2 = _interopRequireDefault(_ToggleSearch);
 
 var _prefs = __webpack_require__(226);
 
 var _selectors = __webpack_require__(242);
 
-__webpack_require__(1242);
+__webpack_require__(1317);
 
 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
 
 class ProjectSearch extends _react.Component {
 
   constructor(props) {
     super(props);
 
@@ -41569,17 +41624,17 @@ var _text = __webpack_require__(389);
 var _actions = __webpack_require__(244);
 
 var _actions2 = _interopRequireDefault(_actions);
 
 var _selectors = __webpack_require__(242);
 
 var _devtoolsConfig = __webpack_require__(828);
 
-__webpack_require__(1243);
+__webpack_require__(1318);
 
 var _classnames = __webpack_require__(175);
 
 var _classnames2 = _interopRequireDefault(_classnames);
 
 var _Outline = __webpack_require__(1145);
 
 var _Outline2 = _interopRequireDefault(_Outline);
@@ -41815,17 +41870,17 @@ var _redux = __webpack_require__(3);
 var _reactRedux = __webpack_require__(1189);
 
 var _actions = __webpack_require__(244);
 
 var _actions2 = _interopRequireDefault(_actions);
 
 var _selectors = __webpack_require__(242);
 
-__webpack_require__(1244);
+__webpack_require__(1319);
 
 var _PreviewFunction = __webpack_require__(798);
 
 var _PreviewFunction2 = _interopRequireDefault(_PreviewFunction);
 
 var _lodash = __webpack_require__(2);
 
 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
@@ -41873,17 +41928,17 @@ class Outline extends _react.Component {
   renderClassFunctions(functions) {
     var classFunctions = functions.filter(func => func.name != "anonymous" && !!func.klass);
 
     if (classFunctions.length == 0) {
       return null;
     }
 
     var klass = classFunctions[0].klass;
-    var klassFunc = (0, _lodash.find)(functions, func => func.name === klass);
+    var klassFunc = functions.find(func => func.name === klass);
 
     return _react2.default.createElement(
       "div",
       { className: "outline-list__class" },
       _react2.default.createElement(
         "h2",
         null,
         klassFunc ? this.renderFunction(klassFunc) : klass
@@ -41950,17 +42005,17 @@ var _redux = __webpack_require__(3);
 var _react = __webpack_require__(0);
 
 var _actions = __webpack_require__(244);
 
 var _actions2 = _interopRequireDefault(_actions);
 
 var _selectors = __webpack_require__(242);
 
-__webpack_require__(1256);
+__webpack_require__(1330);
 
 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
 
 class EmptyLines extends _react.Component {
 
   componentDidMount() {
     this.disableEmptyLines();
   }
@@ -42203,42 +42258,41 @@ class SourcesTree extends _react.Compone
     }
 
     (0, _devtoolsLaunchpad.showMenu)(event, menuOptions);
   }
 
   renderItem(item, depth, focused, _, expanded, _ref) {
     var setExpanded = _ref.setExpanded;
 
-    var arrow = (0, _sourcesTree.nodeHasChildren)(item) ? _react2.default.createElement(_Svg2.default, {
-      name: "arrow",
-      className: (0, _classnames2.default)({
+    var arrow = (0, _sourcesTree.nodeHasChildren)(item) ? _react2.default.createElement("img", {
+      className: (0, _classnames2.default)("arrow", {
         expanded: expanded
       }),
       onClick: e => {
         e.stopPropagation();
-        setExpanded(item, !expanded);
+        setExpanded(item, !expanded, e.altKey);
       }
     }) : _react2.default.createElement("i", { className: "no-arrow" });
 
     var icon = this.getIcon(item, depth);
     var paddingDir = "paddingRight";
     if (document.body && document.body.parentElement) {
       paddingDir = document.body.parentElement.dir == "ltr" ? "paddingLeft" : "paddingRight";
     }
 
     return _react2.default.createElement(
       "div",
       {
         className: (0, _classnames2.default)("node", { focused }),
         style: { [paddingDir]: `${depth * 15 + 5}px` },
         key: item.path,
-        onClick: () => {
+        onClick: e => {
           this.selectItem(item);
-          setExpanded(item, !expanded);
+          setExpanded(item, !expanded, e.altKey);
         },
         onContextMenu: e => this.onContextMenu(e, item)
       },
       arrow,
       icon,
       _react2.default.createElement(
         "span",
         { className: "label" },
@@ -42337,17 +42391,17 @@ Object.defineProperty(exports, "__esModu
   value: true
 });
 exports.Workers = undefined;
 
 var _react = __webpack_require__(0);
 
 var _react2 = _interopRequireDefault(_react);
 
-__webpack_require__(1265);
+__webpack_require__(1340);
 
 var _reactRedux = __webpack_require__(1189);
 
 var _selectors = __webpack_require__(242);
 
 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
 
 class Workers extends _react.PureComponent {
@@ -42451,17 +42505,17 @@ module.exports = "<!-- This Source Code 
 
 var _require = __webpack_require__(0),
     Component = _require.Component,
     createFactory = _require.createFactory,
     dom = _require.DOM,
     PropTypes = _require.PropTypes;
 
 var Tree = createFactory(__webpack_require__(1007).Tree);
-__webpack_require__(1251);
+__webpack_require__(1325);
 
 var classnames = __webpack_require__(175);
 var Svg = __webpack_require__(1151);
 
 var _require2 = __webpack_require__(926),
     _require2$REPS = _require2.REPS,
     Rep = _require2$REPS.Rep,
     Grip = _require2$REPS.Grip;
@@ -43429,17 +43483,17 @@ var _editor = __webpack_require__(257);
 
 var _actions = __webpack_require__(244);
 
 var _actions2 = _interopRequireDefault(_actions);
 
 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
 
 function getCallSiteAtLocation(callSites, location) {
-  return (0, _lodash.find)(callSites, callSite => (0, _lodash.isEqualWith)(callSite.location, location, (cloc, loc) => {
+  return callSites.find(callSite => (0, _lodash.isEqualWith)(callSite.location, location, (cloc, loc) => {
     return loc.line === cloc.start.line && loc.column >= cloc.start.column && loc.column <= cloc.end.column;
   }));
 }
 
 class CallSites extends _react.Component {
 
   constructor(props) {
     super(props);
@@ -43693,17 +43747,17 @@ module.exports = networkRequest;
 Object.defineProperty(exports, "__esModule", {
   value: true
 });
 
 var _react = __webpack_require__(0);
 
 var _editor = __webpack_require__(257);
 
-__webpack_require__(1255);
+__webpack_require__(1329);
 
 class CallSite extends _react.Component {
 
   constructor() {
     super();
 
     this.addCallSite = nextProps => {
       var _ref = nextProps || this.props,
@@ -43996,17 +44050,17 @@ var _Modal2 = _interopRequireDefault(_Mo
 var _SearchInput = __webpack_require__(377);
 
 var _SearchInput2 = _interopRequireDefault(_SearchInput);
 
 var _ResultList = __webpack_require__(383);
 
 var _ResultList2 = _interopRequireDefault(_ResultList);
 
-__webpack_require__(1271);
+__webpack_require__(1297);
 
 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
 
 function formatSymbol(symbol) {
   return {
     id: `${symbol.name}:${symbol.location.start.line}`,
     title: symbol.name,
     subtitle: `:${symbol.location.start.line}`,
@@ -44632,17 +44686,17 @@ var _Modal = __webpack_require__(332);
 var _Modal2 = _interopRequireDefault(_Modal);
 
 var _classnames = __webpack_require__(175);
 
 var _classnames2 = _interopRequireDefault(_classnames);
 
 var _text = __webpack_require__(389);
 
-__webpack_require__(1227);
+__webpack_require__(1304);
 
 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
 
 class ShortcutsModal extends _react.Component {
 
   renderPrettyCombos(combo) {
     return combo.split(" ").map(c => _react2.default.createElement(
       "span",
@@ -44832,17 +44886,17 @@ var _react2 = _interopRequireDefault(_re
 var _classnames = __webpack_require__(175);
 
 var _classnames2 = _interopRequireDefault(_classnames);
 
 var _Svg = __webpack_require__(344);
 
 var _Svg2 = _interopRequireDefault(_Svg);
 
-__webpack_require__(1215);
+__webpack_require__(1295);
 
 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
 
 function debugBtn(onClick, type, className, tooltip) {
   var disabled = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : false;
 
   var props = {
     onClick,
@@ -46476,140 +46530,45 @@ function correctIndentation(text) {
   var lines = text.trim().split("\n");
   var indentation = getIndentation(lines);
   var formattedLines = lines.map(_line => _line.replace(new RegExp(`^\\s{0,${indentation - 1}}`), ""));
 
   return formattedLines.join("\n");
 }
 
 /***/ }),
-/* 1215 */
-/***/ (function(module, exports) {
-
-// removed by extract-text-webpack-plugin
-
-/***/ }),
-/* 1216 */
-/***/ (function(module, exports) {
-
-// removed by extract-text-webpack-plugin
-
-/***/ }),
+/* 1215 */,
+/* 1216 */,
 /* 1217 */,
 /* 1218 */,
 /* 1219 */,
 /* 1220 */,
-/* 1221 */
-/***/ (function(module, exports) {
-
-// removed by extract-text-webpack-plugin
-
-/***/ }),
-/* 1222 */
-/***/ (function(module, exports) {
-
-// removed by extract-text-webpack-plugin
-
-/***/ }),
-/* 1223 */
-/***/ (function(module, exports) {
-
-// removed by extract-text-webpack-plugin
-
-/***/ }),
-/* 1224 */
-/***/ (function(module, exports) {
-
-// removed by extract-text-webpack-plugin
-
-/***/ }),
-/* 1225 */
-/***/ (function(module, exports) {
-
-// removed by extract-text-webpack-plugin
-
-/***/ }),
-/* 1226 */
-/***/ (function(module, exports) {
-
-// removed by extract-text-webpack-plugin
-
-/***/ }),
-/* 1227 */
-/***/ (function(module, exports) {
-
-// removed by extract-text-webpack-plugin
-
-/***/ }),
-/* 1228 */
-/***/ (function(module, exports) {
-
-// removed by extract-text-webpack-plugin
-
-/***/ }),
-/* 1229 */
-/***/ (function(module, exports) {
-
-// removed by extract-text-webpack-plugin
-
-/***/ }),
-/* 1230 */
-/***/ (function(module, exports) {
-
-// removed by extract-text-webpack-plugin
-
-/***/ }),
-/* 1231 */
-/***/ (function(module, exports) {
-
-// removed by extract-text-webpack-plugin
-
-/***/ }),
-/* 1232 */
-/***/ (function(module, exports) {
-
-// removed by extract-text-webpack-plugin
-
-/***/ }),
+/* 1221 */,
+/* 1222 */,
+/* 1223 */,
+/* 1224 */,
+/* 1225 */,
+/* 1226 */,
+/* 1227 */,
+/* 1228 */,
+/* 1229 */,
+/* 1230 */,
+/* 1231 */,
+/* 1232 */,
 /* 1233 */
 /***/ (function(module, exports) {
 
 module.exports = "<svg viewBox=\"0 0 256 296\" version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" preserveAspectRatio=\"xMidYMid\"><g><polygon fill=\"#673AB8\" points=\"128 0 256 73.8999491 256 221.699847 128 295.599796 0 221.699847 0 73.8999491\"></polygon><path d=\"M34.8647584,220.478469 C51.8814262,242.25881 105.959701,225.662965 157.014868,185.774297 C208.070035,145.885628 237.255632,97.428608 220.238964,75.6482664 C203.222296,53.8679249 149.144022,70.4637701 98.0888543,110.352439 C47.0336869,150.241107 17.8480906,198.698127 34.8647584,220.478469 Z M42.1343351,214.798853 C36.4908625,207.575537 38.9565723,193.395881 49.7081913,175.544904 C61.0297348,156.747677 80.2490923,135.997367 103.76847,117.622015 C127.287848,99.2466634 152.071368,85.6181573 173.049166,79.1803727 C192.970945,73.066665 207.325915,74.1045667 212.969387,81.3278822 C218.61286,88.5511977 216.14715,102.730854 205.395531,120.581832 C194.073987,139.379058 174.85463,160.129368 151.335252,178.50472 C127.815874,196.880072 103.032354,210.508578 82.054556,216.946362 C62.1327769,223.06007 47.7778077,222.022168 42.1343351,214.798853 Z\" fill=\"#FFFFFF\"></path><path d=\"M220.238964,220.478469 C237.255632,198.698127 208.070035,150.241107 157.014868,110.352439 C105.959701,70.4637701 51.8814262,53.8679249 34.8647584,75.6482664 C17.8480906,97.428608 47.0336869,145.885628 98.0888543,185.774297 C149.144022,225.662965 203.222296,242.25881 220.238964,220.478469 Z M212.969387,214.798853 C207.325915,222.022168 192.970945,223.06007 173.049166,216.946362 C152.071368,210.508578 127.287848,196.880072 103.76847,178.50472 C80.2490923,160.129368 61.0297348,139.379058 49.7081913,120.581832 C38.9565723,102.730854 36.4908625,88.5511977 42.1343351,81.3278822 C47.7778077,74.1045667 62.1327769,73.066665 82.054556,79.1803727 C103.032354,85.6181573 127.815874,99.2466634 151.335252,117.622015 C174.85463,135.997367 194.073987,156.747677 205.395531,175.544904 C216.14715,193.395881 218.61286,207.575537 212.969387,214.798853 Z\" fill=\"#FFFFFF\"></path><path d=\"M127.551861,167.666971 C138.378632,167.666971 147.155465,158.890139 147.155465,148.063368 C147.155465,137.236596 138.378632,128.459764 127.551861,128.459764 C116.72509,128.459764 107.948257,137.236596 107.948257,148.063368 C107.948257,158.890139 116.72509,167.666971 127.551861,167.666971 L127.551861,167.666971 Z\" fill=\"#FFFFFF\"></path></g></svg>"
 
 /***/ }),
-/* 1234 */
-/***/ (function(module, exports) {
-
-// removed by extract-text-webpack-plugin
-
-/***/ }),
-/* 1235 */
-/***/ (function(module, exports) {
-
-// removed by extract-text-webpack-plugin
-
-/***/ }),
-/* 1236 */
-/***/ (function(module, exports) {
-
-// removed by extract-text-webpack-plugin
-
-/***/ }),
-/* 1237 */
-/***/ (function(module, exports) {
-
-// removed by extract-text-webpack-plugin
-
-/***/ }),
-/* 1238 */
-/***/ (function(module, exports) {
-
-// removed by extract-text-webpack-plugin
-
-/***/ }),
+/* 1234 */,
+/* 1235 */,
+/* 1236 */,
+/* 1237 */,
+/* 1238 */,
 /* 1239 */
 /***/ (function(module, exports, __webpack_require__) {
 
 "use strict";
 
 
 Object.defineProperty(exports, "__esModule", {
   value: true
@@ -46621,16 +46580,21 @@ exports.createTreeNodeMatcher = createTr
 var _url = __webpack_require__(334);
 
 var _utils = __webpack_require__(18);
 
 /*
  * Gets domain from url (without www prefix)
  */
 function getDomain(url) {
+  // TODO: define how files should be ordered on the browser debugger
+  if (!url) {
+    return null;
+  }
+
   var _parse = (0, _url.parse)(url),
       host = _parse.host;
 
   if (!host) {
     return null;
   }
   return host.startsWith("www.") ? host.substr("www.".length) : host;
 }
@@ -46730,208 +46694,48 @@ function createTreeNodeMatcher(part, isD
     // Specialied matcher, when we are looking for domain position.
     return createTreeNodeMatcherWithDebuggeeHost(debuggeeHost);
   }
   // Rest of the cases, without mentioned above.
   return createTreeNodeMatcherWithNameAndOther(part, isDir, debuggeeHost);
 }
 
 /***/ }),
-/* 1240 */
-/***/ (function(module, exports) {
-
-// removed by extract-text-webpack-plugin
-
-/***/ }),
-/* 1241 */
-/***/ (function(module, exports) {
-
-// removed by extract-text-webpack-plugin
-
-/***/ }),
-/* 1242 */
-/***/ (function(module, exports) {
-
-// removed by extract-text-webpack-plugin
-
-/***/ }),
-/* 1243 */
-/***/ (function(module, exports) {
-
-// removed by extract-text-webpack-plugin
-
-/***/ }),
-/* 1244 */
-/***/ (function(module, exports) {
-
-// removed by extract-text-webpack-plugin
-
-/***/ }),
-/* 1245 */
-/***/ (function(module, exports) {
-
-// removed by extract-text-webpack-plugin
-
-/***/ }),
-/* 1246 */
-/***/ (function(module, exports) {
-
-// removed by extract-text-webpack-plugin
-
-/***/ }),
-/* 1247 */
-/***/ (function(module, exports) {
-
-// removed by extract-text-webpack-plugin
-
-/***/ }),
-/* 1248 */
-/***/ (function(module, exports) {
-
-// removed by extract-text-webpack-plugin
-
-/***/ }),
-/* 1249 */
-/***/ (function(module, exports) {
-
-// removed by extract-text-webpack-plugin
-
-/***/ }),
-/* 1250 */
-/***/ (function(module, exports) {
-
-// removed by extract-text-webpack-plugin
-
-/***/ }),
-/* 1251 */
-/***/ (function(module, exports) {
-
-// removed by extract-text-webpack-plugin
-
-/***/ }),
-/* 1252 */
-/***/ (function(module, exports) {
-
-// removed by extract-text-webpack-plugin
-
-/***/ }),
-/* 1253 */
-/***/ (function(module, exports) {
-
-// removed by extract-text-webpack-plugin
-
-/***/ }),
-/* 1254 */
-/***/ (function(module, exports) {
-
-// removed by extract-text-webpack-plugin
-
-/***/ }),
-/* 1255 */
-/***/ (function(module, exports) {
-
-// removed by extract-text-webpack-plugin
-
-/***/ }),
-/* 1256 */
-/***/ (function(module, exports) {
-
-// removed by extract-text-webpack-plugin
-
-/***/ }),
-/* 1257 */
-/***/ (function(module, exports) {
-
-// removed by extract-text-webpack-plugin
-
-/***/ }),
-/* 1258 */
-/***/ (function(module, exports) {
-
-// removed by extract-text-webpack-plugin
-
-/***/ }),
-/* 1259 */
-/***/ (function(module, exports) {
-
-// removed by extract-text-webpack-plugin
-
-/***/ }),
-/* 1260 */
-/***/ (function(module, exports) {
-
-// removed by extract-text-webpack-plugin
-
-/***/ }),
-/* 1261 */
-/***/ (function(module, exports) {
-
-// removed by extract-text-webpack-plugin
-
-/***/ }),
-/* 1262 */
-/***/ (function(module, exports) {
-
-// removed by extract-text-webpack-plugin
-
-/***/ }),
-/* 1263 */
-/***/ (function(module, exports) {
-
-// removed by extract-text-webpack-plugin
-
-/***/ }),
-/* 1264 */
-/***/ (function(module, exports) {
-
-// removed by extract-text-webpack-plugin
-
-/***/ }),
-/* 1265 */
-/***/ (function(module, exports) {
-
-// removed by extract-text-webpack-plugin
-
-/***/ }),
-/* 1266 */
-/***/ (function(module, exports) {
-
-// removed by extract-text-webpack-plugin
-
-/***/ }),
-/* 1267 */
-/***/ (function(module, exports) {
-
-// removed by extract-text-webpack-plugin
-
-/***/ }),
-/* 1268 */
-/***/ (function(module, exports) {
-
-// removed by extract-text-webpack-plugin
-
-/***/ }),
-/* 1269 */
-/***/ (function(module, exports) {
-
-// removed by extract-text-webpack-plugin
-
-/***/ }),
-/* 1270 */
-/***/ (function(module, exports) {
-
-// removed by extract-text-webpack-plugin
-
-/***/ }),
-/* 1271 */
-/***/ (function(module, exports) {
-
-// removed by extract-text-webpack-plugin
-
-/***/ }),
+/* 1240 */,
+/* 1241 */,
+/* 1242 */,
+/* 1243 */,
+/* 1244 */,
+/* 1245 */,
+/* 1246 */,
+/* 1247 */,
+/* 1248 */,
+/* 1249 */,
+/* 1250 */,
+/* 1251 */,
+/* 1252 */,
+/* 1253 */,
+/* 1254 */,
+/* 1255 */,
+/* 1256 */,
+/* 1257 */,
+/* 1258 */,
+/* 1259 */,
+/* 1260 */,
+/* 1261 */,
+/* 1262 */,
+/* 1263 */,
+/* 1264 */,
+/* 1265 */,
+/* 1266 */,
+/* 1267 */,
+/* 1268 */,
+/* 1269 */,
+/* 1270 */,
+/* 1271 */,
 /* 1272 */,
 /* 1273 */,
 /* 1274 */,
 /* 1275 */,
 /* 1276 */,
 /* 1277 */,
 /* 1278 */,
 /* 1279 */,
@@ -46945,11 +46749,512 @@ function createTreeNodeMatcher(part, isD
 /* 1287 */,
 /* 1288 */,
 /* 1289 */,
 /* 1290 */
 /***/ (function(module, exports) {
 
 module.exports = "<svg version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" x=\"0px\" y=\"0px\" viewBox=\"0 0 512 512\" enable-background=\"new 0 0 512 512\" xml:space=\"preserve\"><g id=\"Layer_2\"><path fill=\"#132028\" d=\"M190.475,376V203.308H81.266c-27.129,0-50.139,26-58.222,62.035c-9.877,1.302-17.62,13.541-17.62,28.455 c0,14.914,7.743,27.153,17.62,28.455c7.291,32.507,26.733,56.84,50.385,61.294v68.669h395.95V376H190.475z\"></path></g><g id=\"Layer_3\"><path fill=\"#575A5B\" d=\"M490.712,427.977c0,30.941-25.082,56.023-56.023,56.023c-25.804,0-47.519-17.451-54.023-41.19 c-6.504,23.739-28.219,41.19-54.023,41.19c-30.941,0-56.023-25.082-56.023-56.023c0-30.941,25.082-56.023,56.023-56.023 c25.804,0,47.519,17.451,54.023,41.19c6.504-23.739,28.219-41.19,54.023-41.19C465.629,371.954,490.712,397.036,490.712,427.977z M161.24,203.308l29.75-113.845H94.232l29.75,113.845h-13.668c-33.865,0-61.319,40.513-61.319,90.489 c0,49.976,27.453,90.489,61.319,90.489H294.27V203.308H161.24z M162.321,420.431c-13.164,0-24.458,8.002-29.285,19.408 c-4.826-11.405-16.121-19.408-29.284-19.408c-17.554,0-31.785,14.23-31.785,31.784c0,17.554,14.23,31.785,31.785,31.785 c13.164,0,24.458-8.002,29.284-19.408C137.863,475.998,149.157,484,162.321,484c17.554,0,31.784-14.23,31.784-31.785 C194.106,434.661,179.875,420.431,162.321,420.431z\"></path></g><g id=\"Layer_4\"><path fill=\"#FFB636\" d=\"M200.78,384.287h-16.028c-20.105,0-36.403-40.513-36.403-90.489c0-49.976,16.298-90.489,36.403-90.489 h16.028c-20.105,0-36.403,40.513-36.403,90.489C164.378,343.773,180.676,384.287,200.78,384.287z M122.236,293.797 c0-49.976,16.298-90.489,36.403-90.489H142.61c-20.105,0-36.403,40.513-36.403,90.489c0,49.976,16.298,90.489,36.403,90.489h16.028 C138.534,384.287,122.236,343.773,122.236,293.797z\"></path></g><g id=\"Layer_5\"><path fill=\"#FF473E\" d=\"M489.353,384.287H294.27V85.761h195.083V384.287z M74.21,384.103h-7.99c-2.436,0-4.707,1.48-6.035,3.934 l-43.633,80.594C13.436,474.387,16.874,482,22.587,482h52.826c4.027,0,7.271-3.968,7.199-8.806l-1.203-80.594 C81.339,387.883,78.136,384.103,74.21,384.103z\"></path></g><g id=\"Layer_6\"><path fill=\"#EF2020\" d=\"M497.28,66.397H286.342c-5.92,0-10.72,4.8-10.72,10.72v1.626c0,5.92,4.8,10.72,10.72,10.72H497.28 c5.921,0,10.72-4.8,10.72-10.72v-1.626C508,71.197,503.201,66.397,497.28,66.397z\"></path></g><g id=\"Layer_7\"><path fill=\"#76DFFF\" d=\"M371.466,257.523h-40.952c-3.976,0-7.2-3.224-7.2-7.2V124.018c0-3.976,3.224-7.2,7.2-7.2h40.952 c3.976,0,7.2,3.224,7.2,7.2v126.305C378.666,254.3,375.442,257.523,371.466,257.523z M460.474,250.323V124.018 c0-3.976-3.224-7.2-7.2-7.2h-40.952c-3.976,0-7.2,3.224-7.2,7.2v126.305c0,3.976,3.224,7.2,7.2,7.2h40.952 C457.251,257.523,460.474,254.3,460.474,250.323z\"></path></g><g id=\"Layer_8\"><path fill=\"#132028\" d=\"M489.353,339.586H294.27v-36.582h195.083V339.586z M111.17,52L94.206,89.463h96.758L174,52H111.17z M326.643,414.954c-7.192,0-13.023,5.831-13.023,13.023S319.451,441,326.643,441c7.192,0,13.023-5.831,13.023-13.023 S333.835,414.954,326.643,414.954z M434.689,414.954c-7.192,0-13.023,5.831-13.023,13.023S427.496,441,434.689,441 s13.023-5.831,13.023-13.023S441.881,414.954,434.689,414.954z M103.752,444.827c-4.081,0-7.389,3.308-7.389,7.389 s3.308,7.389,7.389,7.389c4.081,0,7.389-3.308,7.389-7.389S107.833,444.827,103.752,444.827z M162.321,444.827 c-4.081,0-7.389,3.308-7.389,7.389s3.308,7.389,7.389,7.389s7.389-3.308,7.389-7.389S166.402,444.827,162.321,444.827z\"></path></g><g id=\"Layer_9\"><path fill=\"#FFB636\" d=\"M196.709,444.208h-92.957c-4.91,0-8.891-3.98-8.891-8.891s3.98-8.891,8.891-8.891h90.449l36.759-22.53 c1.398-0.857,3.006-1.311,4.646-1.311H459.54c4.91,0,8.891,3.98,8.891,8.891s-3.98,8.891-8.891,8.891H238.114l-36.759,22.53 C199.957,443.755,198.349,444.208,196.709,444.208z\"></path></g><g id=\"Layer_10\"><path fill=\"#ADB7BC\" d=\"M69.849,393.079c-5.787,0-10.485-4.685-10.5-10.475c-0.014-5.799,4.676-10.512,10.475-10.525l413.924-1 c0.009,0,0.018,0,0.026,0c5.787,0,10.485,4.685,10.499,10.475c0.014,5.799-4.676,10.512-10.475,10.525l-413.924,1 C69.867,393.079,69.857,393.079,69.849,393.079z\"></path></g></svg>"
 
+/***/ }),
+/* 1291 */,
+/* 1292 */,
+/* 1293 */,
+/* 1294 */,
+/* 1295 */
+/***/ (function(module, exports) {
+
+// removed by extract-text-webpack-plugin
+
+/***/ }),
+/* 1296 */
+/***/ (function(module, exports) {
+
+// removed by extract-text-webpack-plugin
+
+/***/ }),
+/* 1297 */
+/***/ (function(module, exports) {
+
+// removed by extract-text-webpack-plugin
+
+/***/ }),
+/* 1298 */
+/***/ (function(module, exports) {
+
+// removed by extract-text-webpack-plugin
+
+/***/ }),
+/* 1299 */
+/***/ (function(module, exports) {
+
+// removed by extract-text-webpack-plugin
+
+/***/ }),
+/* 1300 */
+/***/ (function(module, exports) {
+
+// removed by extract-text-webpack-plugin
+
+/***/ }),
+/* 1301 */
+/***/ (function(module, exports) {
+
+// removed by extract-text-webpack-plugin
+
+/***/ }),
+/* 1302 */
+/***/ (function(module, exports) {
+
+// removed by extract-text-webpack-plugin
+
+/***/ }),
+/* 1303 */
+/***/ (function(module, exports) {
+
+// removed by extract-text-webpack-plugin
+
+/***/ }),
+/* 1304 */
+/***/ (function(module, exports) {
+
+// removed by extract-text-webpack-plugin
+
+/***/ }),
+/* 1305 */
+/***/ (function(module, exports) {
+
+// removed by extract-text-webpack-plugin
+
+/***/ }),
+/* 1306 */
+/***/ (function(module, exports) {
+
+// removed by extract-text-webpack-plugin
+
+/***/ }),
+/* 1307 */
+/***/ (function(module, exports) {
+
+// removed by extract-text-webpack-plugin
+
+/***/ }),
+/* 1308 */
+/***/ (function(module, exports) {
+
+// removed by extract-text-webpack-plugin
+
+/***/ }),
+/* 1309 */
+/***/ (function(module, exports) {
+
+// removed by extract-text-webpack-plugin
+
+/***/ }),
+/* 1310 */
+/***/ (function(module, exports) {
+
+// removed by extract-text-webpack-plugin
+
+/***/ }),
+/* 1311 */
+/***/ (function(module, exports) {
+
+// removed by extract-text-webpack-plugin
+
+/***/ }),
+/* 1312 */
+/***/ (function(module, exports) {
+
+// removed by extract-text-webpack-plugin
+
+/***/ }),
+/* 1313 */
+/***/ (function(module, exports) {
+
+// removed by extract-text-webpack-plugin
+
+/***/ }),
+/* 1314 */
+/***/ (function(module, exports) {
+
+// removed by extract-text-webpack-plugin
+
+/***/ }),
+/* 1315 */
+/***/ (function(module, exports) {
+
+// removed by extract-text-webpack-plugin
+
+/***/ }),
+/* 1316 */
+/***/ (function(module, exports) {
+
+// removed by extract-text-webpack-plugin
+
+/***/ }),
+/* 1317 */
+/***/ (function(module, exports) {
+
+// removed by extract-text-webpack-plugin
+
+/***/ }),
+/* 1318 */
+/***/ (function(module, exports) {
+
+// removed by extract-text-webpack-plugin
+
+/***/ }),
+/* 1319 */
+/***/ (function(module, exports) {
+
+// removed by extract-text-webpack-plugin
+
+/***/ }),
+/* 1320 */
+/***/ (function(module, exports) {
+
+// removed by extract-text-webpack-plugin
+
+/***/ }),
+/* 1321 */
+/***/ (function(module, exports) {
+
+// removed by extract-text-webpack-plugin
+
+/***/ }),
+/* 1322 */
+/***/ (function(module, exports) {
+
+// removed by extract-text-webpack-plugin
+
+/***/ }),
+/* 1323 */
+/***/ (function(module, exports) {
+
+// removed by extract-text-webpack-plugin
+
+/***/ }),
+/* 1324 */
+/***/ (function(module, exports) {
+
+// removed by extract-text-webpack-plugin
+
+/***/ }),
+/* 1325 */
+/***/ (function(module, exports) {
+
+// removed by extract-text-webpack-plugin
+
+/***/ }),
+/* 1326 */
+/***/ (function(module, exports) {
+
+// removed by extract-text-webpack-plugin
+
+/***/ }),
+/* 1327 */
+/***/ (function(module, exports) {
+
+// removed by extract-text-webpack-plugin
+
+/***/ }),
+/* 1328 */
+/***/ (function(module, exports) {
+
+// removed by extract-text-webpack-plugin
+
+/***/ }),
+/* 1329 */
+/***/ (function(module, exports) {
+
+// removed by extract-text-webpack-plugin
+
+/***/ }),
+/* 1330 */
+/***/ (function(module, exports) {
+
+// removed by extract-text-webpack-plugin
+
+/***/ }),
+/* 1331 */
+/***/ (function(module, exports) {
+
+// removed by extract-text-webpack-plugin
+
+/***/ }),
+/* 1332 */
+/***/ (function(module, exports) {
+
+// removed by extract-text-webpack-plugin
+
+/***/ }),
+/* 1333 */
+/***/ (function(module, exports) {
+
+// removed by extract-text-webpack-plugin
+
+/***/ }),
+/* 1334 */
+/***/ (function(module, exports) {
+
+// removed by extract-text-webpack-plugin
+
+/***/ }),
+/* 1335 */
+/***/ (function(module, exports) {
+
+// removed by extract-text-webpack-plugin
+
+/***/ }),
+/* 1336 */
+/***/ (function(module, exports) {
+
+// removed by extract-text-webpack-plugin
+
+/***/ }),
+/* 1337 */
+/***/ (function(module, exports) {
+
+// removed by extract-text-webpack-plugin
+
+/***/ }),
+/* 1338 */
+/***/ (function(module, exports) {
+
+// removed by extract-text-webpack-plugin
+
+/***/ }),
+/* 1339 */
+/***/ (function(module, exports) {
+
+// removed by extract-text-webpack-plugin
+
+/***/ }),
+/* 1340 */
+/***/ (function(module, exports) {
+
+// removed by extract-text-webpack-plugin
+
+/***/ }),
+/* 1341 */
+/***/ (function(module, exports) {
+
+// removed by extract-text-webpack-plugin
+
+/***/ }),
+/* 1342 */
+/***/ (function(module, exports) {
+
+// removed by extract-text-webpack-plugin
+
+/***/ }),
+/* 1343 */
+/***/ (function(module, exports) {
+
+// removed by extract-text-webpack-plugin
+
+/***/ }),
+/* 1344 */
+/***/ (function(module, exports) {
+
+// removed by extract-text-webpack-plugin
+
+/***/ }),
+/* 1345 */
+/***/ (function(module, exports) {
+
+// removed by extract-text-webpack-plugin
+
+/***/ }),
+/* 1346 */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+
+Object.defineProperty(exports, "__esModule", {
+  value: true
+});
+
+var _react = __webpack_require__(0);
+
+var _react2 = _interopRequireDefault(_react);
+
+var _reactRedux = __webpack_require__(1189);
+
+var _redux = __webpack_require__(3);
+
+var _selectors = __webpack_require__(242);
+
+var _actions = __webpack_require__(244);
+
+var _actions2 = _interopRequireDefault(_actions);
+
+var _Modal = __webpack_require__(332);
+
+var _Modal2 = _interopRequireDefault(_Modal);
+
+var _SearchInput = __webpack_require__(377);
+
+var _SearchInput2 = _interopRequireDefault(_SearchInput);
+
+__webpack_require__(1297);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+class GotoLineModal extends _react.Component {
+
+  constructor(props) {
+    super(props);
+
+    this.onClick = e => {
+      e.stopPropagation();
+    };
+
+    this.onChange = e => {
+      var selectedSource = this.props.selectedSource;
+
+      if (!selectedSource || !selectedSource.get("text")) {
+        return;
+      }
+
+      this.setState({ query: e.target.value });
+    };
+
+    this.closeModal = () => {
+      this.props.closeActiveSearch();
+      this.props.clearHighlightLineRange();
+    };
+
+    this.onKeyUp = e => {
+      e.preventDefault();
+      var _props = this.props,
+          selectSource = _props.selectSource,
+          selectedSource = _props.selectedSource,
+          enabled = _props.enabled;
+      var query = this.state.query;
+
+
+      if (!enabled || !selectedSource) {
+        return;
+      }
+
+      if (e.key === "Enter" && query != null) {
+        var linenumber = parseInt(query.replace(/[^\d+]/g, ""), 10);
+        if (!isNaN(linenumber)) {
+          selectSource(selectedSource.get("id"), { line: linenumber });
+        }
+        this.closeModal();
+        return;
+      }
+
+      if (e.key === "Tab") {
+        this.closeModal();
+        return;
+      }
+      return;
+    };
+
+    this.buildPlaceHolder = () => L10N.getFormatStr("gotoLineModal.placeholder");
+
+    this.state = { query: "" };
+  }
+
+  renderInput() {
+    var query = this.state.query;
+
+
+    return _react2.default.createElement(
+      "div",
+      { key: "input", className: "input-wrapper" },
+      _react2.default.createElement(_SearchInput2.default, {
+        query: query,
+        placeholder: this.buildPlaceHolder(),
+        onChange: this.onChange,
+        onKeyUp: this.onKeyUp,
+        handleClose: this.closeModal
+      })
+    );
+  }
+
+  render() {
+    var enabled = this.props.enabled;
+
+
+    if (!enabled) {
+      return null;
+    }
+
+    return _react2.default.createElement(
+      _Modal2.default,
+      { "in": enabled, handleClose: this.closeModal },
+      this.renderInput()
+    );
+  }
+}
+
+exports.default = (0, _reactRedux.connect)(state => {
+  var source = (0, _selectors.getSelectedSource)(state);
+  return {
+    enabled: Boolean((0, _selectors.getActiveSearch)(state) === "line" && source)
+  };
+}, dispatch => (0, _redux.bindActionCreators)(_actions2.default, dispatch))(GotoLineModal);
+
+/***/ }),
+/* 1347 */
+/***/ (function(module, exports) {
+
+module.exports = "<!-- This Source Code Form is subject to the terms of the Mozilla Public - License, v. 2.0. If a copy of the MPL was not distributed with this - file, You can obtain one at http://mozilla.org/MPL/2.0/. --><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 16 16\" fill=\"#D92215\"><path d=\"M8 14.5c-3.6 0-6.5-2.9-6.5-6.5S4.4 1.5 8 1.5s6.5 2.9 6.5 6.5-2.9 6.5-6.5 6.5zm0-12C5 2.5 2.5 5 2.5 8S5 13.5 8 13.5 13.5 11 13.5 8 11 2.5 8 2.5z\"></path><circle cx=\"5\" cy=\"6\" r=\"1\" transform=\"translate(1 1)\"></circle><circle cx=\"9\" cy=\"6\" r=\"1\" transform=\"translate(1 1)\"></circle><path d=\"M5.5 11c-.1 0-.2 0-.3-.1-.2-.1-.3-.4-.1-.7C6 9 7 8.5 8.1 8.5c1.7.1 2.8 1.7 2.8 1.8.2.2.1.5-.1.7-.2.1-.6 0-.7-.2 0 0-.9-1.3-2-1.3-.7 0-1.4.4-2.1 1.3-.2.2-.4.2-.5.2z\"></path></svg>"
+
+/***/ }),
+/* 1348 */
+/***/ (function(module, exports) {
+
+module.exports = "<!-- This Source Code Form is subject to the terms of the Mozilla Public - License, v. 2.0. If a copy of the MPL was not distributed with this - file, You can obtain one at http://mozilla.org/MPL/2.0/. --><svg viewBox=\"0 0 16 16\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M13.917 7C13.44 4.162 10.973 2 8 2 4.686 2 2 4.686 2 8s2.686 6 6 6c2.22 0 4.16-1.207 5.197-3H12c-.912 1.214-2.364 2-4 2-2.76 0-5-2.24-5-5s2.24-5 5-5c2.42 0 4.437 1.718 4.9 4h1.017z\"></path><path d=\"M14 1L8 7h6V1zm-1 1L9 6h4V2z\" fill-rule=\"evenodd\"></path></svg>"
+
+/***/ }),
+/* 1349 */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+
+var React = __webpack_require__(0);
+var InlineSVG = __webpack_require__(1205);
+
+var _require = __webpack_require__(828),
+    isDevelopment = _require.isDevelopment;
+
+var svg = {
+  "rocket": __webpack_require__(1126)
+};
+
+function Svg(_ref) {
+  var name = _ref.name,
+      className = _ref.className,
+      onClick = _ref.onClick,
+      ariaLabel = _ref["aria-label"];
+
+  className = `${name} ${className || ""}`;
+  if (name === "subSettings") {
+    className = "";
+  }
+
+  console.log({ name });
+
+  var props = {
+    className,
+    onClick,
+    ["aria-label"]: ariaLabel,
+    src: svg[name]
+  };
+
+  return React.createElement(InlineSVG, props);
+}
+
+// Svg.displayName = "Svg";
+
+module.exports = Svg;
+
 /***/ })
 /******/ ]);
 });
\ No newline at end of file
--- a/devtools/client/debugger/new/parser-worker.js
+++ b/devtools/client/debugger/new/parser-worker.js
@@ -28721,170 +28721,161 @@ module.exports = isEmpty;
 /* 1016 */,
 /* 1017 */,
 /* 1018 */,
 /* 1019 */,
 /* 1020 */,
 /* 1021 */,
 /* 1022 */,
 /* 1023 */
-/***/ (function(module, __webpack_exports__, __webpack_require__) {
-
-"use strict";
-Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
-/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "extractScriptTags", function() { return extractScriptTags; });
-/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "generateWhitespace", function() { return generateWhitespace; });
-/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "getCandidateScriptLocations", function() { return getCandidateScriptLocations; });
-/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "parseScript", function() { return parseScript; });
-/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "parseScripts", function() { return parseScripts; });
-/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "parseScriptTags", function() { return parseScriptTags; });
-const babylon = __webpack_require__(435);
-const types = __webpack_require__(493);
-
-const startScript = /<script[^>]*>/im;
-const endScript = /<\/script\s*>/im;
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+
+Object.defineProperty(exports, "__esModule", {
+  value: true
+});
+
+function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }
+
+var babylon = __webpack_require__(435);
+var types = __webpack_require__(493);
+
+var startScript = /<script[^>]*>/im;
+var endScript = /<\/script\s*>/im;
 // https://stackoverflow.com/questions/5034781/js-regex-to-split-by-line#comment5633979_5035005
-const newLines = /\r\n|[\n\v\f\r\x85\u2028\u2029]/;
+var newLines = /\r\n|[\n\v\f\r\x85\u2028\u2029]/;
 
 function getCandidateScriptLocations(source, index) {
-  const i = index || 0;
-  const str = source.substring(i);
-
-  const startMatch = startScript.exec(str);
+  var i = index || 0;
+  var str = source.substring(i);
+
+  var startMatch = startScript.exec(str);
   if (startMatch) {
-    const startsAt = startMatch.index + startMatch[0].length;
-    const afterStart = str.substring(startsAt);
-    const endMatch = endScript.exec(afterStart);
+    var startsAt = startMatch.index + startMatch[0].length;
+    var afterStart = str.substring(startsAt);
+    var endMatch = endScript.exec(afterStart);
     if (endMatch) {
-      const locLength = endMatch.index;
-      const locIndex = i + startsAt;
-
-      return [
-        adjustForLineAndColumn(source, {
-          index: locIndex,
-          length: locLength,
-          source: source.substring(locIndex, locIndex + locLength)
-        }),
-        ...getCandidateScriptLocations(
-          source,
-          locIndex + locLength + endMatch[0].length
-        )
-      ];
+      var locLength = endMatch.index;
+      var locIndex = i + startsAt;
+
+      return [adjustForLineAndColumn(source, {
+        index: locIndex,
+        length: locLength,
+        source: source.substring(locIndex, locIndex + locLength)
+      })].concat(_toConsumableArray(getCandidateScriptLocations(source, locIndex + locLength + endMatch[0].length)));
     }
   }
 
   return [];
 }
 
-function parseScript({source, line}) {
+function parseScript(_ref) {
+  var source = _ref.source,
+      line = _ref.line;
+
   // remove empty or only whitespace scripts
   if (source.length === 0 || /^\s+$/.test(source)) {
     return null;
   }
 
   try {
     return babylon.parse(source, {
       sourceType: "script",
       startLine: line
     });
   } catch (e) {
     return null;
   }
 }
 
-function parseScripts(locations, parser = parseScript) {
+function parseScripts(locations) {
+  var parser = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : parseScript;
+
   return locations.map(parser);
 }
 
 function generateWhitespace(length) {
   return Array.from(new Array(length + 1)).join(" ");
 }
 
 function calcLineAndColumn(source, index) {
-  const lines = source
-    .substring(0, index)
-    .split(newLines)
-  const line = lines.length;
-  const column = lines.pop().length + 1;
+  var lines = source.substring(0, index).split(newLines);
+  var line = lines.length;
+  var column = lines.pop().length + 1;
 
   return {
-    column,
-    line
+    column: column,
+    line: line
   };
 }
 
 function adjustForLineAndColumn(fullSource, location) {
-  const {column, line} = calcLineAndColumn(fullSource, location.index);
+  var _calcLineAndColumn = calcLineAndColumn(fullSource, location.index),
+      column = _calcLineAndColumn.column,
+      line = _calcLineAndColumn.line;
+
   return Object.assign({}, location, {
-    line,
-    column,
+    line: line,
+    column: column,
     // prepend whitespace for scripts that do not start on the first column
     source: generateWhitespace(column) + location.source
   });
 }
 
 function parseScriptTags(source, parser) {
-  const scripts = parseScripts(
-    getCandidateScriptLocations(source),
-    parser
-  ).filter(
-    types.isFile
-  ).reduce((main, script) => {
+  var scripts = parseScripts(getCandidateScriptLocations(source), parser).filter(types.isFile).reduce(function (main, script) {
     return {
       statements: main.statements.concat(script.program.body),
       comments: main.comments.concat(script.comments),
       tokens: main.tokens.concat(script.tokens)
     };
   }, {
     statements: [],
     comments: [],
     tokens: []
   });
 
-  const program = types.program(scripts.statements);
-  const file = types.file(
-    program,
-    scripts.comments,
-    scripts.tokens
-  );
-
-  const end = calcLineAndColumn(source, source.length);
+  var program = types.program(scripts.statements);
+  var file = types.file(program, scripts.comments, scripts.tokens);
+
+  var end = calcLineAndColumn(source, source.length);
   file.start = program.start = 0;
   file.end = program.end = source.length;
   file.loc = program.loc = {
     start: {
       line: 1,
       column: 0
     },
-    end
-  }
+    end: end
+  };
 
   return file;
 }
 
 function extractScriptTags(source) {
-  return parseScripts(
-    getCandidateScriptLocations(source),
-    loc => {
-      const ast = parseScript(loc);
-
-      if (ast) {
-        return loc;
-      }
-
-      return null;
-    }
-  ).filter(
-    types.isFile
-  );
-}
-
-/* harmony default export */ __webpack_exports__["default"] = (parseScriptTags);
-
-
+  return parseScripts(getCandidateScriptLocations(source), function (loc) {
+    var ast = parseScript(loc);
+
+    if (ast) {
+      return loc;
+    }
+
+    return null;
+  }).filter(types.isFile);
+}
+
+exports.default = parseScriptTags;
+exports.extractScriptTags = extractScriptTags;
+exports.generateWhitespace = generateWhitespace;
+exports.getCandidateScriptLocations = getCandidateScriptLocations;
+exports.parseScript = parseScript;
+exports.parseScripts = parseScripts;
+exports.parseScriptTags = parseScriptTags;
 
 /***/ }),
 /* 1024 */,
 /* 1025 */,
 /* 1026 */,
 /* 1027 */,
 /* 1028 */,
 /* 1029 */,
deleted file mode 100644
--- a/devtools/client/debugger/new/test/mochitest/browser_dbg-returnvalues.js
+++ /dev/null
@@ -1,12 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/ */
-
-const {
-  setupTestRunner,
-  returnvalues
-} = require("devtools/client/debugger/new/integration-tests");
-
-add_task(function*() {
-  setupTestRunner(this);
-  yield returnvalues(this);
-});
--- a/devtools/client/inspector/fonts/fonts.js
+++ b/devtools/client/inspector/fonts/fonts.js
@@ -49,17 +49,17 @@ FontInspector.prototype = {
       onPreviewFonts: this.onPreviewFonts,
       onShowAllFont: this.onShowAllFont,
     });
 
     let provider = createElement(Provider, {
       id: "fontinspector",
       key: "fontinspector",
       store: this.store,
-      title: INSPECTOR_L10N.getStr("inspector.sidebar.fontInspectorTitle")
+      title: INSPECTOR_L10N.getStr("inspector.sidebar.fontInspectorTitle"),
     }, app);
 
     // Expose the provider to let inspector.js use it in setupSidebar.
     this.provider = provider;
 
     this.inspector.selection.on("new-node-front", this.onNewNode);
     this.inspector.sidebar.on("fontinspector-selected", this.onNewNode);
 
--- a/devtools/client/inspector/grids/grid-inspector.js
+++ b/devtools/client/inspector/grids/grid-inspector.js
@@ -22,18 +22,16 @@ const {
   updateShowInfiniteLines,
 } = require("./actions/highlighter-settings");
 
 const CSS_GRID_COUNT_HISTOGRAM_ID = "DEVTOOLS_NUMBER_OF_CSS_GRIDS_IN_A_PAGE";
 
 const SHOW_GRID_AREAS = "devtools.gridinspector.showGridAreas";
 const SHOW_GRID_LINE_NUMBERS = "devtools.gridinspector.showGridLineNumbers";
 const SHOW_INFINITE_LINES_PREF = "devtools.gridinspector.showInfiniteLines";
-// @remove after release 56 (See Bug 1355747)
-const PROMOTE_COUNT_PREF = "devtools.promote.layoutview";
 
 // Default grid colors.
 const GRID_COLORS = [
   "#9400FF",
   "#DF00A9",
   "#0A84FF",
   "#12BC00",
   "#EA8000",
@@ -564,19 +562,16 @@ GridInspector.prototype = {
    * Finally, refresh the layout view if it is visible.
    */
   onSidebarSelect() {
     if (!this.isPanelVisible()) {
       this.inspector.reflowTracker.untrackReflows(this, this.onReflow);
       return;
     }
 
-    // @remove after release 56 (See Bug 1355747)
-    Services.prefs.setIntPref(PROMOTE_COUNT_PREF, 0);
-
     this.inspector.reflowTracker.trackReflows(this, this.onReflow);
     this.updateGridPanel();
   },
 
   /**
    * Handler for a change in the input checkboxes in the GridList component.
    * Toggles on/off the grid highlighter for the provided grid container element.
    *
--- a/devtools/client/inspector/grids/test/head.js
+++ b/devtools/client/inspector/grids/test/head.js
@@ -11,20 +11,18 @@ Services.scriptloader.loadSubScript(
   "chrome://mochitests/content/browser/devtools/client/inspector/test/head.js",
   this);
 
 // Load the shared Redux helpers into this compartment.
 Services.scriptloader.loadSubScript(
   "chrome://mochitests/content/browser/devtools/client/framework/test/shared-redux-head.js",
   this);
 
-Services.prefs.setBoolPref("devtools.promote.layoutview.showPromoteBar", false);
 Services.prefs.setIntPref("devtools.toolbox.footer.height", 350);
 registerCleanupFunction(() => {
-  Services.prefs.clearUserPref("devtools.promote.layoutview.showPromoteBar");
   Services.prefs.clearUserPref("devtools.toolbox.footer.height");
 });
 
 const HIGHLIGHTER_TYPE = "CssGridHighlighter";
 
 /**
  * Simulate a color change in a given color picker tooltip.
  *
--- a/devtools/client/inspector/layout/components/App.js
+++ b/devtools/client/inspector/layout/components/App.js
@@ -13,17 +13,16 @@ const { LocalizationHelper } = require("
 
 const BoxModel = createFactory(require("devtools/client/inspector/boxmodel/components/BoxModel"));
 const Grid = createFactory(require("devtools/client/inspector/grids/components/Grid"));
 
 const BoxModelTypes = require("devtools/client/inspector/boxmodel/types");
 const GridTypes = require("devtools/client/inspector/grids/types");
 
 const Accordion = createFactory(require("./Accordion"));
-const LayoutPromoteBar = createFactory(require("./LayoutPromoteBar"));
 
 const BOXMODEL_STRINGS_URI = "devtools/client/locales/boxmodel.properties";
 const BOXMODEL_L10N = new LocalizationHelper(BOXMODEL_STRINGS_URI);
 
 const LAYOUT_STRINGS_URI = "devtools/client/locales/layout.properties";
 const LAYOUT_L10N = new LocalizationHelper(LAYOUT_STRINGS_URI);
 
 const BOXMODEL_OPENED_PREF = "devtools.layout.boxmodel.opened";
@@ -36,38 +35,32 @@ const App = createClass({
   propTypes: {
     boxModel: PropTypes.shape(BoxModelTypes.boxModel).isRequired,
     getSwatchColorPickerTooltip: PropTypes.func.isRequired,
     grids: PropTypes.arrayOf(PropTypes.shape(GridTypes.grid)).isRequired,
     highlighterSettings: PropTypes.shape(GridTypes.highlighterSettings).isRequired,
     setSelectedNode: PropTypes.func.isRequired,
     showBoxModelProperties: PropTypes.bool.isRequired,
     onHideBoxModelHighlighter: PropTypes.func.isRequired,
-    onPromoteLearnMoreClick: PropTypes.func.isRequired,
     onSetGridOverlayColor: PropTypes.func.isRequired,
     onShowBoxModelEditor: PropTypes.func.isRequired,
     onShowBoxModelHighlighter: PropTypes.func.isRequired,
     onShowBoxModelHighlighterForNode: PropTypes.func.isRequired,
     onToggleGridHighlighter: PropTypes.func.isRequired,
     onToggleShowGridLineNumbers: PropTypes.func.isRequired,
     onToggleShowInfiniteLines: PropTypes.func.isRequired,
   },
 
   mixins: [ addons.PureRenderMixin ],
 
   render() {
-    let { onPromoteLearnMoreClick } = this.props;
-
     return dom.div(
       {
         id: "layout-container",
       },
-      LayoutPromoteBar({
-        onPromoteLearnMoreClick,
-      }),
       Accordion({
         items: [
           {
             header: LAYOUT_L10N.getStr("layout.header"),
             component: Grid,
             componentProps: this.props,
             opened: Services.prefs.getBoolPref(GRID_OPENED_PREF),
             onToggled: () => {
deleted file mode 100644
--- a/devtools/client/inspector/layout/components/LayoutPromoteBar.js
+++ /dev/null
@@ -1,76 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-"use strict";
-
-/**
- * !!!!                      TO BE REMOVED AFTER RELEASE 56                          !!!!
- * !!!!                                                                              !!!!
- * !!!! This file is a temporary panel that should only be used for release 56 to    !!!!
- * !!!! promote the new layout panel. After release 56, it should be removed.        !!!!
- * !!!! See bug 1355747.                                                             !!!!
- */
-
-const Services = require("Services");
-const { addons, createClass, DOM: dom, PropTypes } =
-  require("devtools/client/shared/vendor/react");
-
-const { LocalizationHelper } = require("devtools/shared/l10n");
-
-const LAYOUT_STRINGS_URI = "devtools/client/locales/layout.properties";
-const LAYOUT_L10N = new LocalizationHelper(LAYOUT_STRINGS_URI);
-
-const SHOW_PROMOTE_BAR_PREF = "devtools.promote.layoutview.showPromoteBar";
-
-module.exports = createClass({
-
-  displayName: "LayoutPromoteBar",
-
-  propTypes: {
-    onPromoteLearnMoreClick: PropTypes.func.isRequired,
-  },
-
-  mixins: [ addons.PureRenderMixin ],
-
-  getInitialState() {
-    return {
-      showPromoteBar: Services.prefs.getBoolPref(SHOW_PROMOTE_BAR_PREF)
-    };
-  },
-
-  onPromoteCloseButtonClick() {
-    Services.prefs.setBoolPref(SHOW_PROMOTE_BAR_PREF, false);
-    this.setState({ showPromoteBar: false });
-  },
-
-  render() {
-    let { onPromoteLearnMoreClick } = this.props;
-    let { showPromoteBar } = this.state;
-
-    return showPromoteBar ?
-      dom.div({ className: "layout-promote-bar" },
-        dom.span({ className: "layout-promote-info-icon" }),
-        dom.div({ className: "layout-promote-message" },
-          LAYOUT_L10N.getStr("layout.promoteMessage"),
-          dom.a(
-            {
-              className: "layout-promote-learn-more-link theme-link",
-              href: "#",
-              onClick: onPromoteLearnMoreClick,
-            },
-            LAYOUT_L10N.getStr("layout.learnMore")
-          )
-        ),
-        dom.button(
-          {
-            className: "layout-promote-close-button devtools-button",
-            onClick: this.onPromoteCloseButtonClick,
-          }
-        )
-      )
-      :
-      null;
-  },
-
-});
--- a/devtools/client/inspector/layout/components/moz.build
+++ b/devtools/client/inspector/layout/components/moz.build
@@ -3,10 +3,9 @@
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 DevToolsModules(
     'Accordion.css',
     'Accordion.js',
     'App.js',
-    'LayoutPromoteBar.js',
 )
--- a/devtools/client/inspector/layout/layout.js
+++ b/devtools/client/inspector/layout/layout.js
@@ -1,40 +1,30 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 "use strict";
 
-const Services = require("Services");
-
 const { createFactory, createElement } = require("devtools/client/shared/vendor/react");
 const { Provider } = require("devtools/client/shared/vendor/react-redux");
 
 const App = createFactory(require("./components/App"));
 
 const { LocalizationHelper } = require("devtools/shared/l10n");
 const INSPECTOR_L10N =
   new LocalizationHelper("devtools/client/locales/inspector.properties");
 
-// @remove after release 56 (See Bug 1355747)
-const PROMOTE_COUNT_PREF = "devtools.promote.layoutview";
-
-// @remove after release 56 (See Bug 1355747)
-const GRID_LINK = "https://www.mozilla.org/en-US/developer/css-grid/?utm_source=gridtooltip&utm_medium=devtools&utm_campaign=cssgrid_layout";
-
 loader.lazyRequireGetter(this, "GridInspector", "devtools/client/inspector/grids/grid-inspector");
 
 function LayoutView(inspector, window) {
   this.document = window.document;
   this.inspector = inspector;
   this.store = inspector.store;
 
-  this.onPromoteLearnMoreClick = this.onPromoteLearnMoreClick.bind(this);
-
   this.init();
 }
 
 LayoutView.prototype = {
 
   init() {
     if (!this.inspector) {
       return;
@@ -60,30 +50,25 @@ LayoutView.prototype = {
       onShowGridCellHighlight,
       onShowGridLineNamesHighlight,
       onToggleGridHighlighter,
       onToggleShowGridAreas,
       onToggleShowGridLineNumbers,
       onToggleShowInfiniteLines,
     } = this.gridInspector.getComponentProps();
 
-    let {
-      onPromoteLearnMoreClick,
-    } = this;
-
     let app = App({
       getSwatchColorPickerTooltip,
       setSelectedNode,
       /**
        * Shows the box model properties under the box model if true, otherwise, hidden by
        * default.
        */
       showBoxModelProperties: true,
       onHideBoxModelHighlighter,
-      onPromoteLearnMoreClick,
       onSetGridOverlayColor,
       onShowBoxModelEditor,
       onShowBoxModelHighlighter,
       onShowBoxModelHighlighterForNode,
       onShowGridAreaHighlight,
       onShowGridCellHighlight,
       onShowGridLineNamesHighlight,
       onToggleGeometryEditor,
@@ -93,20 +78,16 @@ LayoutView.prototype = {
       onToggleShowInfiniteLines,
     });
 
     let provider = createElement(Provider, {
       id: "layoutview",
       key: "layoutview",
       store: this.store,
       title: INSPECTOR_L10N.getStr("inspector.sidebar.layoutViewTitle2"),
-      // @remove after release 56 (See Bug 1355747)
-      badge: Services.prefs.getIntPref(PROMOTE_COUNT_PREF) > 0 ?
-        INSPECTOR_L10N.getStr("inspector.sidebar.newBadge") : null,
-      showBadge: () => Services.prefs.getIntPref(PROMOTE_COUNT_PREF) > 0,
     }, app);
 
     // Expose the provider to let inspector.js use it in setupSidebar.
     this.provider = provider;
   },
 
   /**
    * Destruction function called when the inspector is destroyed. Cleans up references.
@@ -114,16 +95,11 @@ LayoutView.prototype = {
   destroy() {
     this.gridInspector.destroy();
 
     this.document = null;
     this.inspector = null;
     this.store = null;
   },
 
-  onPromoteLearnMoreClick() {
-    let browserWin = this.inspector.target.tab.ownerDocument.defaultView;
-    browserWin.openUILinkIn(GRID_LINK, "current");
-  }
-
 };
 
 module.exports = LayoutView;
--- a/devtools/client/jar.mn
+++ b/devtools/client/jar.mn
@@ -291,8 +291,11 @@ devtools.jar:
     skin/images/firebug/command-frames.svg (themes/images/firebug/command-frames.svg)
     skin/images/firebug/command-paintflashing.svg (themes/images/firebug/command-paintflashing.svg)
     skin/images/firebug/command-responsivemode.svg (themes/images/firebug/command-responsivemode.svg)
     skin/images/firebug/command-scratchpad.svg (themes/images/firebug/command-scratchpad.svg)
     skin/images/firebug/command-screenshot.svg (themes/images/firebug/command-screenshot.svg)
     skin/images/firebug/command-measure.svg (themes/images/firebug/command-measure.svg)
     skin/images/firebug/command-rulers.svg (themes/images/firebug/command-rulers.svg)
     skin/images/firebug/command-noautohide.svg (themes/images/firebug/command-noautohide.svg)
+
+    # Debugger
+    skin/images/debugger/arrow.svg (themes/images/debugger/arrow.svg)
--- a/devtools/client/locales/en-US/debugger.properties
+++ b/devtools/client/locales/en-US/debugger.properties
@@ -638,16 +638,21 @@ variablesSeparatorLabel=:
 # in the watch expressions list as a separator between the code and evaluation.
 watchExpressionsSeparatorLabel2=\u0020→
 
 # LOCALIZATION NOTE (functionSearchSeparatorLabel): The text that is displayed
 # in the functions search panel as a separator between function's inferred name
 # and its real name (if available).
 functionSearchSeparatorLabel=←
 
+# LOCALIZATION NOTE(gotoLineModal.placeholder): The placeholder
+# text displayed when the user searches for specific lines in a file
+gotoLineModal.placeholder=Go to line…
+gotoLineModal.key=CmdOrCtrl+Shift+;
+
 # LOCALIZATION NOTE(symbolSearch.search.functionsPlaceholder): The placeholder
 # text displayed when the user searches for functions in a file
 symbolSearch.search.functionsPlaceholder=Search functions…
 
 # LOCALIZATION NOTE(symbolSearch.search.variablesPlaceholder): The placeholder
 # text displayed when the user searches for variables in a file
 symbolSearch.search.variablesPlaceholder=Search variables…
 
--- a/devtools/client/locales/en-US/layout.properties
+++ b/devtools/client/locales/en-US/layout.properties
@@ -39,16 +39,8 @@ layout.overlayMultipleGrids=Overlay Mult
 
 # LOCALIZATION NOTE (layout.overlayGrid): Alternate header for the list of grid container
 # elements if only one item can be selected.
 layout.overlayGrid=Overlay Grid
 
 # LOCALIZATION NOTE (layout.rowColumnPositions): The row and column position of a grid
 # cell shown in the grid cell infobar when hovering over the CSS grid outline.
 layout.rowColumnPositions=Row %S / Column %S
-
-# LOCALIZATION NOTE (layout.promoteMessage): Text displayed in the promote bar for the
-# layout panel.
-layout.promoteMessage=Explore CSS Grids with the latest CSS Grid Inspector.
-
-# LOCALIZATION NOTE (layout.learnMore): Text for the link displayed in the promote bar
-# for the layout panel.
-layout.learnMore=Learn more…
--- a/devtools/client/preferences/debugger.js
+++ b/devtools/client/preferences/debugger.js
@@ -7,20 +7,16 @@ pref("devtools.debugger.new-debugger-fro
 pref("devtools.debugger.enabled", true);
 pref("devtools.debugger.chrome-debugging-host", "localhost");
 pref("devtools.debugger.chrome-debugging-websocket", false);
 pref("devtools.debugger.remote-host", "localhost");
 pref("devtools.debugger.remote-timeout", 20000);
 pref("devtools.debugger.pause-on-exceptions", false);
 pref("devtools.debugger.ignore-caught-exceptions", false);
 pref("devtools.debugger.source-maps-enabled", true);
-// Temporarily leave this in place, even though it is unused, so the
-// options pane doesn't break.
-// https://bugzilla.mozilla.org/show_bug.cgi?id=1371849
-pref("devtools.debugger.client-source-maps-enabled", true);
 pref("devtools.debugger.pretty-print-enabled", true);
 pref("devtools.debugger.auto-pretty-print", false);
 pref("devtools.debugger.auto-black-box", true);
 pref("devtools.debugger.workers", false);
 
 // The default Debugger UI settings
 pref("devtools.debugger.prefs-schema-version", "1.0.0");
 pref("devtools.debugger.ui.panes-workers-and-sources-width", 200);
--- a/devtools/client/preferences/devtools.js
+++ b/devtools/client/preferences/devtools.js
@@ -56,23 +56,16 @@ pref("devtools.inspector.imagePreviewToo
 pref("devtools.inspector.showUserAgentStyles", false);
 // Show all native anonymous content (like controls in <video> tags)
 pref("devtools.inspector.showAllAnonymousContent", false);
 // Enable the new color widget
 pref("devtools.inspector.colorWidget.enabled", false);
 // Enable the CSS shapes highlighter
 pref("devtools.inspector.shapesHighlighter.enabled", true);
 
-// Counter to promote the inspector layout view.
-// @remove after release 56 (See Bug 1355747)
-pref("devtools.promote.layoutview", 1);
-// Whether or not to show the promote bar in the layout view
-// @remove after release 56 (See Bug 1355747)
-pref("devtools.promote.layoutview.showPromoteBar", true);
-
 // Grid highlighter preferences
 pref("devtools.gridinspector.gridOutlineMaxColumns", 50);
 pref("devtools.gridinspector.gridOutlineMaxRows", 50);
 pref("devtools.gridinspector.showGridAreas", false);
 pref("devtools.gridinspector.showGridLineNumbers", false);
 pref("devtools.gridinspector.showInfiniteLines", false);
 pref("devtools.gridinspector.showNegativeLineNumbers", false);
 
new file mode 100644
--- /dev/null
+++ b/devtools/client/themes/images/debugger/arrow.svg
@@ -0,0 +1,6 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+   - License, v. 2.0. If a copy of the MPL was not distributed with this
+   - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 16 16">
+  <path d="M8 13.4c-.5 0-.9-.2-1.2-.6L.4 5.2C0 4.7-.1 4.3.2 3.7S1 3 1.6 3h12.8c.6 0 1.2.1 1.4.7.3.6.2 1.1-.2 1.6l-6.4 7.6c-.3.4-.7.5-1.2.5z"/>
+</svg>
\ No newline at end of file
--- a/devtools/client/themes/layout.css
+++ b/devtools/client/themes/layout.css
@@ -44,66 +44,16 @@
 }
 
 .grid-container label {
   display: flex;
   align-items: center;
 }
 
 /**
- * Layout Promote Bar
- */
-
-.layout-promote-bar {
-  align-items: center;
-  background-color: var(--theme-toolbar-background);
-  border-bottom: 1px solid var(--theme-splitter-color);
-  display: flex;
-  font-size: 11px;
-  padding: 5px;
-  transition: all 0.25s ease;
-  width: 100%;
-  -moz-user-select: none;
-}
-
-.layout-promote-bar:hover {
-  background-color: var(--theme-toolbar-hover);
-}
-
-.layout-promote-info-icon {
-  display: inline-block;
-  background-size: 16px;
-  width: 16px;
-  height: 16px;
-  margin: 6px;
-  background-image: url("chrome://browser/skin/info.svg");
-}
-
-.layout-promote-message {
-  flex: 1;
-}
-
-.layout-promote-learn-more-link {
-  margin-inline-start: 5px;
-}
-
-.layout-promote-learn-more-link:hover {
-  text-decoration: underline;
-}
-
-.layout-promote-close-button {
-  margin: 6px;
-}
-
-.layout-promote-close-button::before {
-  background-image: url("chrome://devtools/skin/images/close.svg");
-  margin: -6px 0 0 -6px;
-}
-
-/**
  * Grid Container
  */
 
 #layout-grid-container {
   display: flex;
   flex-direction: column;
   margin: 5px;
 }
--- a/dom/base/CustomElementRegistry.cpp
+++ b/dom/base/CustomElementRegistry.cpp
@@ -403,18 +403,17 @@ CustomElementRegistry::SyncInvokeReactio
 {
   auto callback = CreateCustomElementCallback(aType, aCustomElement, nullptr,
                                               nullptr, aDefinition);
   if (!callback) {
     return;
   }
 
   UniquePtr<CustomElementReaction> reaction(Move(
-    MakeUnique<CustomElementCallbackReaction>(aDefinition,
-                                              Move(callback))));
+    MakeUnique<CustomElementCallbackReaction>(Move(callback))));
 
   RefPtr<SyncInvokeReactionRunnable> runnable =
     new SyncInvokeReactionRunnable(Move(reaction), aCustomElement);
 
   nsContentUtils::AddScriptRunner(runnable);
 }
 
 /* static */ void
@@ -450,18 +449,17 @@ CustomElementRegistry::EnqueueLifecycleC
     if (definition->mObservedAttributes.IsEmpty() ||
         !definition->mObservedAttributes.Contains(attrName)) {
       return;
     }
   }
 
   CustomElementReactionsStack* reactionsStack =
     docGroup->CustomElementReactionsStack();
-  reactionsStack->EnqueueCallbackReaction(aCustomElement, definition,
-                                          Move(callback));
+  reactionsStack->EnqueueCallbackReaction(aCustomElement, Move(callback));
 }
 
 void
 CustomElementRegistry::GetCustomPrototype(nsAtom* aAtom,
                                           JS::MutableHandle<JSObject*> aPrototype)
 {
   mozilla::dom::CustomElementDefinition* definition =
     mCustomDefinitions.GetWeak(aAtom);
@@ -1028,21 +1026,19 @@ void
 CustomElementReactionsStack::EnqueueUpgradeReaction(Element* aElement,
                                                     CustomElementDefinition* aDefinition)
 {
   Enqueue(aElement, new CustomElementUpgradeReaction(aDefinition));
 }
 
 void
 CustomElementReactionsStack::EnqueueCallbackReaction(Element* aElement,
-                                                     CustomElementDefinition* aDefinition,
                                                      UniquePtr<CustomElementCallback> aCustomElementCallback)
 {
-  Enqueue(aElement, new CustomElementCallbackReaction(aDefinition,
-                                                      Move(aCustomElementCallback)));
+  Enqueue(aElement, new CustomElementCallbackReaction(Move(aCustomElementCallback)));
 }
 
 void
 CustomElementReactionsStack::Enqueue(Element* aElement,
                                      CustomElementReaction* aReaction)
 {
   RefPtr<CustomElementData> elementData = aElement->GetCustomElementData();
   MOZ_ASSERT(elementData, "CustomElementData should exist");
@@ -1181,17 +1177,17 @@ NS_IMPL_CYCLE_COLLECTION_TRACE_END
 NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(CustomElementDefinition, AddRef)
 NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(CustomElementDefinition, Release)
 
 
 CustomElementDefinition::CustomElementDefinition(nsAtom* aType,
                                                  nsAtom* aLocalName,
                                                  Function* aConstructor,
                                                  nsTArray<RefPtr<nsAtom>>&& aObservedAttributes,
-                                                 JSObject* aPrototype,
+                                                 JS::Handle<JSObject*> aPrototype,
                                                  LifecycleCallbacks* aCallbacks,
                                                  uint32_t aDocOrder)
   : mType(aType),
     mLocalName(aLocalName),
     mConstructor(new CustomElementConstructor(aConstructor)),
     mObservedAttributes(Move(aObservedAttributes)),
     mPrototype(aPrototype),
     mCallbacks(aCallbacks),
--- a/dom/base/CustomElementRegistry.h
+++ b/dom/base/CustomElementRegistry.h
@@ -160,17 +160,17 @@ struct CustomElementDefinition
 {
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(CustomElementDefinition)
   NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(CustomElementDefinition)
 
   CustomElementDefinition(nsAtom* aType,
                           nsAtom* aLocalName,
                           Function* aConstructor,
                           nsTArray<RefPtr<nsAtom>>&& aObservedAttributes,
-                          JSObject* aPrototype,
+                          JS::Handle<JSObject*> aPrototype,
                           mozilla::dom::LifecycleCallbacks* aCallbacks,
                           uint32_t aDocOrder);
 
   // The type (name) for this custom element.
   RefPtr<nsAtom> mType;
 
   // The localname to (e.g. <button is=type> -- this would be button).
   RefPtr<nsAtom> mLocalName;
@@ -209,50 +209,42 @@ struct CustomElementDefinition
 
 private:
   ~CustomElementDefinition() {}
 };
 
 class CustomElementReaction
 {
 public:
-  explicit CustomElementReaction(CustomElementDefinition* aDefinition)
-    : mDefinition(aDefinition)
-  {
-  }
-
   virtual ~CustomElementReaction() = default;
   virtual void Invoke(Element* aElement, ErrorResult& aRv) = 0;
   virtual void Traverse(nsCycleCollectionTraversalCallback& aCb) const
   {
   }
-
-protected:
-  CustomElementDefinition* mDefinition;
 };
 
 class CustomElementUpgradeReaction final : public CustomElementReaction
 {
 public:
   explicit CustomElementUpgradeReaction(CustomElementDefinition* aDefinition)
-    : CustomElementReaction(aDefinition)
+    : mDefinition(aDefinition)
   {
   }
 
 private:
    virtual void Invoke(Element* aElement, ErrorResult& aRv) override;
+
+   CustomElementDefinition* mDefinition;
 };
 
 class CustomElementCallbackReaction final : public CustomElementReaction
 {
   public:
-    CustomElementCallbackReaction(CustomElementDefinition* aDefinition,
-                                  UniquePtr<CustomElementCallback> aCustomElementCallback)
-      : CustomElementReaction(aDefinition)
-      , mCustomElementCallback(Move(aCustomElementCallback))
+    explicit CustomElementCallbackReaction(UniquePtr<CustomElementCallback> aCustomElementCallback)
+      : mCustomElementCallback(Move(aCustomElementCallback))
     {
     }
 
     virtual void Traverse(nsCycleCollectionTraversalCallback& aCb) const override
     {
       mCustomElementCallback->Traverse(aCb);
     }
 
@@ -286,17 +278,16 @@ public:
   void EnqueueUpgradeReaction(Element* aElement,
                               CustomElementDefinition* aDefinition);
 
   /**
    * Enqueue a custom element callback reaction
    * https://html.spec.whatwg.org/multipage/scripting.html#enqueue-a-custom-element-callback-reaction
    */
   void EnqueueCallbackReaction(Element* aElement,
-                               CustomElementDefinition* aDefinition,
                                UniquePtr<CustomElementCallback> aCustomElementCallback);
 
   // [CEReactions] Before executing the algorithm's steps
   // Push a new element queue onto the custom element reactions stack.
   void CreateAndPushElementQueue();
 
   // [CEReactions] After executing the algorithm's steps
   // Pop the element queue from the custom element reactions stack,
--- a/dom/bindings/CallbackObject.cpp
+++ b/dom/bindings/CallbackObject.cpp
@@ -156,41 +156,57 @@ CallbackObject::CallSetup::CallSetup(Cal
 
   JSObject* wrappedCallback = aCallback->CallbackPreserveColor();
   if (!wrappedCallback) {
     aRv.ThrowDOMException(NS_ERROR_DOM_NOT_SUPPORTED_ERR,
       NS_LITERAL_CSTRING("Cannot execute callback from a nuked compartment."));
     return;
   }
 
-  // First, find the real underlying callback.
-  JSObject* realCallback = js::UncheckedUnwrap(wrappedCallback);
   nsIGlobalObject* globalObject = nullptr;
 
-  // Now get the global for this callback. Note that for the case of
-  // JS-implemented WebIDL we never have a window here.
-  nsGlobalWindow* win = mIsMainThread && !aIsJSImplementedWebIDL
-                          ? xpc::WindowGlobalOrNull(realCallback)
-                          : nullptr;
-  if (win) {
-    MOZ_ASSERT(win->IsInnerWindow());
-    // We don't want to run script in windows that have been navigated away
-    // from.
-    if (!win->AsInner()->HasActiveDocument()) {
-      aRv.ThrowDOMException(NS_ERROR_DOM_NOT_SUPPORTED_ERR,
-        NS_LITERAL_CSTRING("Refusing to execute function from window "
-                           "whose document is no longer active."));
-      return;
+  {
+    // First, find the real underlying callback.
+    JSObject* realCallback = js::UncheckedUnwrap(wrappedCallback);
+
+    // Check that it's ok to run this callback. JS-implemented WebIDL is always
+    // OK to run, since it runs with Chrome privileges anyway.
+    if (mIsMainThread && !aIsJSImplementedWebIDL) {
+      // Make sure to use realCallback to get the global of the callback
+      // object, not the wrapper.
+      if (!xpc::Scriptability::Get(realCallback).Allowed()) {
+        aRv.ThrowDOMException(NS_ERROR_DOM_NOT_SUPPORTED_ERR,
+          NS_LITERAL_CSTRING("Refusing to execute function from global in which "
+                             "script is disabled."));
+        return;
+      }
     }
-    globalObject = win;
-  } else {
-    // No DOM Window. Store the global.
-    JSObject* global = js::GetGlobalForObjectCrossCompartment(realCallback);
-    globalObject = xpc::NativeGlobal(global);
-    MOZ_ASSERT(globalObject);
+
+    // Now get the global for this callback. Note that for the case of
+    // JS-implemented WebIDL we never have a window here.
+    nsGlobalWindow* win = mIsMainThread && !aIsJSImplementedWebIDL
+                            ? xpc::WindowGlobalOrNull(realCallback)
+                            : nullptr;
+    if (win) {
+      MOZ_ASSERT(win->IsInnerWindow());
+      // We don't want to run script in windows that have been navigated away
+      // from.
+      if (!win->AsInner()->HasActiveDocument()) {
+        aRv.ThrowDOMException(NS_ERROR_DOM_NOT_SUPPORTED_ERR,
+          NS_LITERAL_CSTRING("Refusing to execute function from window "
+                             "whose document is no longer active."));
+        return;
+      }
+      globalObject = win;
+    } else {
+      // No DOM Window. Store the global.
+      JSObject* global = js::GetGlobalForObjectCrossCompartment(realCallback);
+      globalObject = xpc::NativeGlobal(global);
+      MOZ_ASSERT(globalObject);
+    }
   }
 
   // Bail out if there's no useful global. This seems to happen intermittently
   // on gaia-ui tests, probably because nsInProcessTabChildGlobal is returning
   // null in some kind of teardown state.
   if (!globalObject->GetGlobalJSObject()) {
     aRv.ThrowDOMException(NS_ERROR_DOM_NOT_SUPPORTED_ERR,
       NS_LITERAL_CSTRING("Refusing to execute function from global which is "
@@ -222,32 +238,16 @@ CallbackObject::CallSetup::CallSetup(Cal
   // CallbackPreserveColor() variant), and stick it in a Rooted before it can
   // go gray again.
   // Nothing before us in this function can trigger a CC, so it's safe to wait
   // until here it do the unmark. This allows us to construct mRootedCallable
   // with the cx from mAutoEntryScript, avoiding the cost of finding another
   // JSContext. (Rooted<> does not care about requests or compartments.)
   mRootedCallable.emplace(cx, aCallback->CallbackOrNull());
 
-  // JS-implemented WebIDL is always OK to run, since it runs with Chrome
-  // privileges anyway.
-  if (mIsMainThread && !aIsJSImplementedWebIDL) {
-    // Check that it's ok to run this callback at all.
-    // Make sure to use realCallback to get the global of the callback object,
-    // not the wrapper.
-    bool allowed = xpc::Scriptability::Get(realCallback).Allowed();
-
-    if (!allowed) {
-      aRv.ThrowDOMException(NS_ERROR_DOM_NOT_SUPPORTED_ERR,
-        NS_LITERAL_CSTRING("Refusing to execute function from global in which "
-                           "script is disabled."));
-      return;
-    }
-  }
-
   mAsyncStack.emplace(cx, aCallback->GetCreationStack());
   if (*mAsyncStack) {
     mAsyncStackSetter.emplace(cx, *mAsyncStack, aExecutionReason);
   }
 
   // Enter the compartment of our callback, so we can actually work with it.
   //
   // Note that if the callback is a wrapper, this will not be the same
--- a/dom/ipc/TabChild.cpp
+++ b/dom/ipc/TabChild.cpp
@@ -411,17 +411,16 @@ TabChild::TabChild(nsIContentChild* aMan
   , mTabGroup(aTabGroup)
   , mRemoteFrame(nullptr)
   , mManager(aManager)
   , mChromeFlags(aChromeFlags)
   , mMaxTouchPoints(0)
   , mActiveSuppressDisplayport(0)
   , mLayersId(0)
   , mBeforeUnloadListeners(0)
-  , mLayersConnected(false)
   , mDidFakeShow(false)
   , mNotified(false)
   , mTriedBrowserInit(false)
   , mOrientation(eScreenOrientation_PortraitPrimary)
   , mIgnoreKeyPressEvent(false)
   , mHasValidInnerSize(false)
   , mDestroyed(false)
   , mUniqueId(aTabId)
@@ -1171,17 +1170,17 @@ TabChild::RecvLoadURL(const nsCString& a
 }
 
 void
 TabChild::DoFakeShow(const TextureFactoryIdentifier& aTextureFactoryIdentifier,
                      const uint64_t& aLayersId,
                      const CompositorOptions& aCompositorOptions,
                      PRenderFrameChild* aRenderFrame, const ShowInfo& aShowInfo)
 {
-  mLayersConnected = aRenderFrame ? true : false;
+  mLayersConnected = aRenderFrame ? Some(true) : Some(false);
   InitRenderingState(aTextureFactoryIdentifier, aLayersId, aCompositorOptions, aRenderFrame);
   RecvShow(ScreenIntSize(0, 0), aShowInfo, mParentIsActive, nsSizeMode_Normal);
   mDidFakeShow = true;
 }
 
 void
 TabChild::ApplyShowInfo(const ShowInfo& aInfo)
 {
@@ -1270,17 +1269,17 @@ mozilla::ipc::IPCResult
 TabChild::RecvInitRendering(const TextureFactoryIdentifier& aTextureFactoryIdentifier,
                             const uint64_t& aLayersId,
                             const CompositorOptions& aCompositorOptions,
                             const bool& aLayersConnected,
                             PRenderFrameChild* aRenderFrame)
 {
   MOZ_ASSERT((!mDidFakeShow && aRenderFrame) || (mDidFakeShow && !aRenderFrame));
 
-  mLayersConnected = aLayersConnected;
+  mLayersConnected = Some(aLayersConnected);
   InitRenderingState(aTextureFactoryIdentifier, aLayersId, aCompositorOptions, aRenderFrame);
   return IPC_OK();
 }
 
 mozilla::ipc::IPCResult
 TabChild::RecvUpdateDimensions(const DimensionInfo& aDimensionInfo)
 {
     if (!mRemoteFrame) {
@@ -2795,27 +2794,29 @@ void
 TabChild::InitRenderingState(const TextureFactoryIdentifier& aTextureFactoryIdentifier,
                              const uint64_t& aLayersId,
                              const CompositorOptions& aCompositorOptions,
                              PRenderFrameChild* aRenderFrame)
 {
     mPuppetWidget->InitIMEState();
 
     if (!aRenderFrame) {
+      mLayersConnected = Some(false);
       NS_WARNING("failed to construct RenderFrame");
       return;
     }
 
     MOZ_ASSERT(aLayersId != 0);
     mTextureFactoryIdentifier = aTextureFactoryIdentifier;
 
     // Pushing layers transactions directly to a separate
     // compositor context.
     PCompositorBridgeChild* compositorChild = CompositorBridgeChild::Get();
     if (!compositorChild) {
+      mLayersConnected = Some(false);
       NS_WARNING("failed to get CompositorBridgeChild instance");
       return;
     }
 
     mCompositorOptions = Some(aCompositorOptions);
 
     mRemoteFrame = static_cast<RenderFrameChild*>(aRenderFrame);
     if (aLayersId != 0) {
@@ -2824,54 +2825,79 @@ TabChild::InitRenderingState(const Textu
       if (!sTabChildren) {
         sTabChildren = new TabChildMap;
       }
       MOZ_ASSERT(!sTabChildren->Get(aLayersId));
       sTabChildren->Put(aLayersId, this);
       mLayersId = aLayersId;
     }
 
-    LayerManager* lm = mPuppetWidget->GetLayerManager();
-    if (lm->AsWebRenderLayerManager()) {
-      lm->AsWebRenderLayerManager()->Initialize(compositorChild,
-                                                wr::AsPipelineId(aLayersId),
-                                                &mTextureFactoryIdentifier);
+    MOZ_ASSERT(!mPuppetWidget->HasLayerManager());
+    bool success = false;
+    if (mLayersConnected == Some(true)) {
+      success = CreateRemoteLayerManager(compositorChild);
+    }
+
+    if (success) {
+      MOZ_ASSERT(mLayersConnected == Some(true));
+      // Succeeded to create "remote" layer manager
       ImageBridgeChild::IdentifyCompositorTextureHost(mTextureFactoryIdentifier);
       gfx::VRManagerChild::IdentifyTextureHost(mTextureFactoryIdentifier);
       InitAPZState();
-    }
-
-    ShadowLayerForwarder* lf =
-        mPuppetWidget->GetLayerManager(
-            nullptr, mTextureFactoryIdentifier.mParentBackend)
-                ->AsShadowForwarder();
-    if (lf) {
-      nsTArray<LayersBackend> backends;
-      backends.AppendElement(mTextureFactoryIdentifier.mParentBackend);
-      PLayerTransactionChild* shadowManager =
-          compositorChild->SendPLayerTransactionConstructor(backends, aLayersId);
-      if (shadowManager) {
-        lf->SetShadowManager(shadowManager);
-        lf->IdentifyTextureHost(mTextureFactoryIdentifier);
-        ImageBridgeChild::IdentifyCompositorTextureHost(mTextureFactoryIdentifier);
-        gfx::VRManagerChild::IdentifyTextureHost(mTextureFactoryIdentifier);
-        InitAPZState();
-      }
+    } else {
+      // Fallback to BasicManager
+      mLayersConnected = Some(false);
     }
 
     nsCOMPtr<nsIObserverService> observerService =
         mozilla::services::GetObserverService();
 
     if (observerService) {
         observerService->AddObserver(this,
                                      BEFORE_FIRST_PAINT,
                                      false);
     }
 }
 
+bool
+TabChild::CreateRemoteLayerManager(mozilla::layers::PCompositorBridgeChild* aCompositorChild)
+{
+  MOZ_ASSERT(aCompositorChild);
+
+  bool success = false;
+  if (gfxVars::UseWebRender()) {
+    success = mPuppetWidget->CreateRemoteLayerManager([&] (LayerManager* aLayerManager) -> bool {
+      MOZ_ASSERT(aLayerManager->AsWebRenderLayerManager());
+      return aLayerManager->AsWebRenderLayerManager()->Initialize(aCompositorChild,
+                                                                  wr::AsPipelineId(mLayersId),
+                                                                  &mTextureFactoryIdentifier);
+    });
+  } else {
+    nsTArray<LayersBackend> ignored;
+    PLayerTransactionChild* shadowManager = aCompositorChild->SendPLayerTransactionConstructor(ignored, LayersId());
+    if (shadowManager &&
+        shadowManager->SendGetTextureFactoryIdentifier(&mTextureFactoryIdentifier) &&
+        mTextureFactoryIdentifier.mParentBackend != LayersBackend::LAYERS_NONE)
+    {
+      success = true;
+    }
+    if (!success) {
+      NS_WARNING("failed to allocate layer transaction");
+    } else {
+      success = mPuppetWidget->CreateRemoteLayerManager([&] (LayerManager* aLayerManager) -> bool {
+        ShadowLayerForwarder* lf = aLayerManager->AsShadowForwarder();
+        lf->SetShadowManager(shadowManager);
+        lf->IdentifyTextureHost(mTextureFactoryIdentifier);
+        return true;
+      });
+    }
+  }
+  return success;
+}
+
 void
 TabChild::InitAPZState()
 {
   if (!mCompositorOptions->UseAPZ()) {
     return;
   }
   auto cbc = CompositorBridgeChild::Get();
 
@@ -3159,51 +3185,27 @@ TabChild::ReinitRendering()
   // PLayerTransaction constructor message arrives on the cross-process
   // compositor bridge.
   CompositorOptions options;
   SendEnsureLayersConnected(&options);
   mCompositorOptions = Some(options);
 
   bool success = false;
   RefPtr<CompositorBridgeChild> cb = CompositorBridgeChild::Get();
-  if (gfxVars::UseWebRender()) {
-    success = mPuppetWidget->RecreateLayerManager([&] (LayerManager* aLayerManager) -> bool {
-      MOZ_ASSERT(aLayerManager->AsWebRenderLayerManager());
-      return aLayerManager->AsWebRenderLayerManager()->Initialize(cb,
-                                                                  wr::AsPipelineId(mLayersId),
-                                                                  &mTextureFactoryIdentifier);
-    });
-  } else {
-    nsTArray<LayersBackend> ignored;
-    PLayerTransactionChild* shadowManager = cb->SendPLayerTransactionConstructor(ignored, LayersId());
-    if (shadowManager &&
-        shadowManager->SendGetTextureFactoryIdentifier(&mTextureFactoryIdentifier) &&
-        mTextureFactoryIdentifier.mParentBackend != LayersBackend::LAYERS_NONE)
-    {
-      success = true;
-    }
-    if (!success) {
-      NS_WARNING("failed to re-allocate layer transaction");
-      return;
-    }
-
-    success = mPuppetWidget->RecreateLayerManager([&] (LayerManager* aLayerManager) -> bool {
-      ShadowLayerForwarder* lf = aLayerManager->AsShadowForwarder();
-      lf->SetShadowManager(shadowManager);
-      lf->IdentifyTextureHost(mTextureFactoryIdentifier);
-      return true;
-    });
+
+  if (cb) {
+    success = CreateRemoteLayerManager(cb);
   }
 
   if (!success) {
     NS_WARNING("failed to recreate layer manager");
     return;
   }
 
-  mLayersConnected = true;
+  mLayersConnected = Some(true);
   ImageBridgeChild::IdentifyCompositorTextureHost(mTextureFactoryIdentifier);
   gfx::VRManagerChild::IdentifyTextureHost(mTextureFactoryIdentifier);
 
   InitAPZState();
 
   nsCOMPtr<nsIDocument> doc(GetDocument());
   doc->NotifyLayerManagerRecreated();
 }
--- a/dom/ipc/TabChild.h
+++ b/dom/ipc/TabChild.h
@@ -58,16 +58,17 @@ class RenderFrameChild;
 } // namespace layout
 
 namespace layers {
 class APZChild;
 class APZEventState;
 class AsyncDragMetrics;
 class IAPZCTreeManager;
 class ImageCompositeNotification;
+class PCompositorBridgeChild;
 } // namespace layers
 
 namespace widget {
 struct AutoCacheNativeKeyCommands;
 } // namespace widget
 
 namespace dom {
 
@@ -604,17 +605,17 @@ public:
     nsCOMPtr<nsIDocShell> docShell = do_QueryInterface(webNav);
     return GetFrom(docShell);
   }
 
   static TabChild* GetFrom(nsIPresShell* aPresShell);
   static TabChild* GetFrom(uint64_t aLayersId);
 
   uint64_t LayersId() { return mLayersId; }
-  bool IsLayersConnected() { return mLayersConnected; }
+  Maybe<bool> IsLayersConnected() { return mLayersConnected; }
 
   void DidComposite(uint64_t aTransactionId,
                     const TimeStamp& aCompositeStart,
                     const TimeStamp& aCompositeEnd);
 
   void DidRequestComposite(const TimeStamp& aCompositeReqStart,
                            const TimeStamp& aCompositeReqEnd);
 
@@ -879,16 +880,18 @@ private:
 
   void DispatchWheelEvent(const WidgetWheelEvent& aEvent,
                           const ScrollableLayerGuid& aGuid,
                           const uint64_t& aInputBlockId);
 
   void InternalSetDocShellIsActive(bool aIsActive,
                                    bool aPreserveLayers);
 
+  bool CreateRemoteLayerManager(mozilla::layers::PCompositorBridgeChild* aCompositorChild);
+
   class DelayedDeleteRunnable;
 
   TextureFactoryIdentifier mTextureFactoryIdentifier;
   nsCOMPtr<nsIWebNavigation> mWebNav;
   RefPtr<mozilla::dom::TabGroup> mTabGroup;
   RefPtr<PuppetWidget> mPuppetWidget;
   nsCOMPtr<nsIURI> mLastURI;
   RenderFrameChild* mRemoteFrame;
@@ -896,17 +899,17 @@ private:
   RefPtr<TabChildSHistoryListener> mHistoryListener;
   uint32_t mChromeFlags;
   uint32_t mMaxTouchPoints;
   int32_t mActiveSuppressDisplayport;
   uint64_t mLayersId;
   int64_t mBeforeUnloadListeners;
   CSSRect mUnscaledOuterRect;
   nscolor mLastBackgroundColor;
-  bool mLayersConnected;
+  Maybe<bool> mLayersConnected;
   bool mDidFakeShow;
   bool mNotified;
   bool mTriedBrowserInit;
   ScreenOrientationInternal mOrientation;
 
   bool mIgnoreKeyPressEvent;
   RefPtr<APZEventState> mAPZEventState;
   SetAllowedTouchBehaviorCallback mSetAllowedTouchBehaviorCallback;
--- a/editor/libeditor/HTMLEditRules.cpp
+++ b/editor/libeditor/HTMLEditRules.cpp
@@ -5057,40 +5057,42 @@ HTMLEditRules::CheckForEmptyBlock(nsINod
         NS_ENSURE_SUCCESS(rv, rv);
       }
     }
   }
 
   if (emptyBlock && emptyBlock->IsEditable()) {
     nsCOMPtr<nsINode> blockParent = emptyBlock->GetParentNode();
     NS_ENSURE_TRUE(blockParent, NS_ERROR_FAILURE);
-    int32_t offset = blockParent->IndexOf(emptyBlock);
 
     if (HTMLEditUtils::IsListItem(emptyBlock)) {
       // Are we the first list item in the list?
       NS_ENSURE_STATE(htmlEditor);
       if (htmlEditor->IsFirstEditableChild(emptyBlock)) {
         nsCOMPtr<nsINode> listParent = blockParent->GetParentNode();
         NS_ENSURE_TRUE(listParent, NS_ERROR_FAILURE);
-        int32_t listOffset = listParent->IndexOf(blockParent);
         // If we are a sublist, skip the br creation
         if (!HTMLEditUtils::IsList(listParent)) {
+          int32_t listOffset = listParent->IndexOf(blockParent);
+
           // Create a br before list
           NS_ENSURE_STATE(htmlEditor);
           nsCOMPtr<Element> br =
             htmlEditor->CreateBR(listParent, listOffset);
           NS_ENSURE_STATE(br);
           // Adjust selection to be right before it
           nsresult rv = aSelection->Collapse(listParent, listOffset);
           NS_ENSURE_SUCCESS(rv, rv);
         }
         // Else just let selection percolate up.  We'll adjust it in
         // AfterEdit()
       }
     } else {
+      int32_t offset = blockParent->IndexOf(emptyBlock);
+
       if (aAction == nsIEditor::eNext || aAction == nsIEditor::eNextWord ||
           aAction == nsIEditor::eToEndOfLine) {
         // Move to the start of the next node, if any
         nsINode* child = emptyBlock->GetNextSibling();
         nsCOMPtr<nsIContent> nextNode =
           htmlEditor->GetNextNode(blockParent, offset + 1, child, true);
         if (nextNode) {
           EditorDOMPoint pt = GetGoodSelPointForNode(*nextNode, aAction);
@@ -5142,18 +5144,23 @@ HTMLEditRules::CheckForInvisibleBR(Eleme
     nsCOMPtr<nsIContent> rightmostNode =
       mHTMLEditor->GetRightmostChild(&aBlock, true);
 
     if (!rightmostNode) {
       return nullptr;
     }
 
     testNode = rightmostNode->GetParentNode();
+    // Since rightmostNode is always the last child, its index is equal to the
+    // child count, so instead of IndexOf() we use the faster GetChildCount(),
+    // and assert the equivalence below.
+    testOffset = testNode->GetChildCount();
+
     // Use offset + 1, so last node is included in our evaluation
-    testOffset = testNode->IndexOf(rightmostNode) + 1;
+    MOZ_ASSERT(testNode->IndexOf(rightmostNode) + 1 == testOffset);
   } else if (aOffset) {
     testNode = &aBlock;
     // We'll check everything to the left of the input position
     testOffset = aOffset;
   } else {
     return nullptr;
   }
 
@@ -5567,17 +5574,17 @@ HTMLEditRules::GetPromotedPoint(RulesEnd
     // from us, and that are enclosed in the same block.
     nsCOMPtr<nsINode> priorNode =
       htmlEditor->GetPriorHTMLNode(node, offset, child, true);
 
     while (priorNode && priorNode->GetParentNode() &&
            !htmlEditor->IsVisibleBRElement(priorNode) &&
            !IsBlockNode(*priorNode)) {
       offset = priorNode->GetParentNode()->IndexOf(priorNode);
-      child = node;
+      child = priorNode;
       node = priorNode->GetParentNode();
       priorNode = htmlEditor->GetPriorHTMLNode(node, offset, child, true);
     }
 
     // finding the real start for this point.  look up the tree for as long as
     // we are the first node in the container, and as long as we haven't hit
     // the body node.
     nsCOMPtr<nsIContent> nearNode =
new file mode 100644
--- /dev/null
+++ b/editor/libeditor/crashtests/1408170.html
@@ -0,0 +1,20 @@
+<script>
+function jsfuzzer() {
+  try { document.execCommand("insertUnorderedList", false); } catch(e) { }
+  try { document.execCommand("delete", false); } catch(e) { }
+}
+function eventhandler1() {
+  try { window.getSelection().collapse(htmlvar00001,1); } catch(e) { }
+}
+function eventhandler2() {
+  try { htmlvar00002.appendChild(htmlvar00001); } catch(e) { }
+}
+</script>
+<body onload=jsfuzzer()>
+<label id="htmlvar00002" contenteditable="true">
+<details ontoggle="eventhandler2()" open="true">
+</details>
+</label>
+<details ontoggle="eventhandler1()" open="true">
+<font id="htmlvar00001" dir="rtl">
+<summary>
--- a/editor/libeditor/crashtests/crashtests.list
+++ b/editor/libeditor/crashtests/crashtests.list
@@ -85,8 +85,9 @@ load 1383747.html
 load 1383755.html
 load 1383763.html
 load 1384161.html
 load 1388075.html
 load 1393171.html
 load 1402469.html
 load 1402904.html
 load 1405747.html
+load 1408170.html
--- a/editor/libeditor/tests/test_bug1385905.html
+++ b/editor/libeditor/tests/test_bug1385905.html
@@ -13,40 +13,39 @@ https://bugzilla.mozilla.org/show_bug.cg
 <div id="display"></div>
 <div id="editor" contenteditable style="padding: 5px;"><div>contents</div></div>
 <pre id="test">
 </pre>
 
 <script class="testbody" type="application/javascript">
 SimpleTest.waitForExplicitFinish();
 SimpleTest.waitForFocus(() => {
-  SpecialPowers.pushPrefEnv({"set": [["editor.use_div_for_default_newlines", true]]}, () => {
-    function ensureNoMozBR() {
-      for (let br of document.querySelectorAll("#editor > div > br")) {
-        isnot(br.getAttribute("type"), "_moz",
-              "mozBR shouldn't be used with this test");
-      }
+  function ensureNoMozBR() {
+    for (let br of document.querySelectorAll("#editor > div > br")) {
+      isnot(br.getAttribute("type"), "_moz",
+            "mozBR shouldn't be used with this test");
     }
-    var editor = document.getElementById("editor");
-    // Click the left blank area of the first line to set cursor to the start of "contents".
-    synthesizeMouse(editor, 3, 10, {});
-    synthesizeKey("KEY_Enter", { code: "Enter" });
-    is(editor.innerHTML, "<div><br></div><div>contents</div>",
-       "Typing Enter at start of the <div> element should split the <div> element");
-    synthesizeKey("KEY_ArrowUp", { code: "ArrowUp" });
-    synthesizeKey("x", { code: "KeyX" });
-    is(editor.innerHTML, "<div>x<br></div><div>contents</div>",
-       "Typing 'x' at the empty <div> element should just insert 'x' into the <div> element");
-    ensureNoMozBR();
-    synthesizeKey("KEY_Enter", { code: "Enter" });
-    is(editor.innerHTML, "<div>x</div><div><br></div><div>contents</div>",
-       "Typing Enter next to 'x' in the first <div> element should split the <div> element and inserts <br> element to a new <div> element");
-    ensureNoMozBR();
-    synthesizeKey("KEY_Enter", { code: "Enter" });
-    is(editor.innerHTML, "<div>x</div><div><br></div><div><br></div><div>contents</div>",
-       "Typing Enter in the empty <div> should split the <div> element and inserts <br> element to a new <div> element");
-    ensureNoMozBR();
-    SimpleTest.finish();
-  });
+  }
+  document.execCommand("defaultparagraphseparator", false, "div");
+  var editor = document.getElementById("editor");
+  // Click the left blank area of the first line to set cursor to the start of "contents".
+  synthesizeMouse(editor, 3, 10, {});
+  synthesizeKey("KEY_Enter", { code: "Enter" });
+  is(editor.innerHTML, "<div><br></div><div>contents</div>",
+     "Typing Enter at start of the <div> element should split the <div> element");
+  synthesizeKey("KEY_ArrowUp", { code: "ArrowUp" });
+  synthesizeKey("x", { code: "KeyX" });
+  is(editor.innerHTML, "<div>x<br></div><div>contents</div>",
+     "Typing 'x' at the empty <div> element should just insert 'x' into the <div> element");
+  ensureNoMozBR();
+  synthesizeKey("KEY_Enter", { code: "Enter" });
+  is(editor.innerHTML, "<div>x</div><div><br></div><div>contents</div>",
+     "Typing Enter next to 'x' in the first <div> element should split the <div> element and inserts <br> element to a new <div> element");
+  ensureNoMozBR();
+  synthesizeKey("KEY_Enter", { code: "Enter" });
+  is(editor.innerHTML, "<div>x</div><div><br></div><div><br></div><div>contents</div>",
+     "Typing Enter in the empty <div> should split the <div> element and inserts <br> element to a new <div> element");
+  ensureNoMozBR();
+  SimpleTest.finish();
 });
 </script>
 </body>
 </html>
--- a/gfx/layers/ipc/CompositorBridgeChild.cpp
+++ b/gfx/layers/ipc/CompositorBridgeChild.cpp
@@ -89,17 +89,17 @@ CompositorBridgeChild::CompositorBridgeC
   , mFwdTransactionId(0)
   , mDeviceResetSequenceNumber(0)
   , mMessageLoop(MessageLoop::current())
   , mProcessToken(0)
   , mSectionAllocator(nullptr)
   , mPaintLock("CompositorBridgeChild.mPaintLock")
   , mOutstandingAsyncPaints(0)
   , mOutstandingAsyncEndTransaction(false)
-  , mIsWaitingForPaint(false)
+  , mIsDelayingForAsyncPaints(false)
   , mSlowFlushCount(0)
   , mTotalFlushCount(0)
 {
   MOZ_ASSERT(NS_IsMainThread());
 }
 
 CompositorBridgeChild::~CompositorBridgeChild()
 {
@@ -1159,17 +1159,17 @@ CompositorBridgeChild::FlushAsyncPaints(
 
   Maybe<TimeStamp> start;
   if (XRE_IsContentProcess() && gfx::gfxVars::UseOMTP()) {
     start = Some(TimeStamp::Now());
   }
 
   {
     MonitorAutoLock lock(mPaintLock);
-    while (mIsWaitingForPaint) {
+    while (mOutstandingAsyncPaints > 0 || mOutstandingAsyncEndTransaction) {
       lock.Wait();
     }
 
     // It's now safe to free any TextureClients that were used during painting.
     mTextureClientsForAsyncPaint.Clear();
   }
 
   if (start) {
@@ -1193,17 +1193,17 @@ CompositorBridgeChild::NotifyBeginAsyncP
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   MonitorAutoLock lock(mPaintLock);
 
   // We must not be waiting for paints to complete yet. This would imply we
   // started a new paint without waiting for a previous one, which could lead to
   // incorrect rendering or IPDL deadlocks.
-  MOZ_ASSERT(!mIsWaitingForPaint);
+  MOZ_ASSERT(!mIsDelayingForAsyncPaints);
 
   mOutstandingAsyncPaints++;
 
   // Mark texture clients that they are being used for async painting, and
   // make sure we hold them alive on the main thread.
   aState->mTextureClient->AddPaintThreadRef();
   mTextureClientsForAsyncPaint.AppendElement(aState->mTextureClient);
   if (aState->mTextureClientOnWhite) {
@@ -1262,57 +1262,58 @@ CompositorBridgeChild::NotifyFinishedAsy
   // Since this should happen after ALL paints are done and
   // at the end of a transaction, this should always be true.
   MOZ_RELEASE_ASSERT(mOutstandingAsyncPaints == 0);
   MOZ_ASSERT(mOutstandingAsyncEndTransaction);
 
   mOutstandingAsyncEndTransaction = false;
 
   // It's possible that we painted so fast that the main thread never reached
-  // the code that starts delaying messages. If so, mIsWaitingForPaint will be
+  // the code that starts delaying messages. If so, mIsDelayingForAsyncPaints will be
   // false, and we can safely return.
-  if (mIsWaitingForPaint) {
+  if (mIsDelayingForAsyncPaints) {
     ResumeIPCAfterAsyncPaint();
+  }
 
-    // Notify the main thread in case it's blocking. We do this unconditionally
-    // to avoid deadlocking.
-    lock.Notify();
-  }
+  // Notify the main thread in case it's blocking. We do this unconditionally
+  // to avoid deadlocking.
+  lock.Notify();
 }
 
 void
 CompositorBridgeChild::ResumeIPCAfterAsyncPaint()
 {
   // Note: the caller is responsible for holding the lock.
   mPaintLock.AssertCurrentThreadOwns();
   MOZ_ASSERT(PaintThread::IsOnPaintThread());
   MOZ_ASSERT(mOutstandingAsyncPaints == 0);
-  MOZ_ASSERT(mIsWaitingForPaint);
+  MOZ_ASSERT(!mOutstandingAsyncEndTransaction);
+  MOZ_ASSERT(mIsDelayingForAsyncPaints);
 
-  mIsWaitingForPaint = false;
+  mIsDelayingForAsyncPaints = false;
 
   // It's also possible that the channel has shut down already.
   if (!mCanSend || mActorDestroyed) {
     return;
   }
 
   GetIPCChannel()->StopPostponingSends();
 }
 
 void
 CompositorBridgeChild::PostponeMessagesIfAsyncPainting()
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   MonitorAutoLock lock(mPaintLock);
 
-  MOZ_ASSERT(!mIsWaitingForPaint);
+  MOZ_ASSERT(!mIsDelayingForAsyncPaints);
 
   // We need to wait for async paints and the async end transaction as
   // it will do texture synchronization
   if (mOutstandingAsyncPaints > 0 || mOutstandingAsyncEndTransaction) {
-    mIsWaitingForPaint = true;
+    mIsDelayingForAsyncPaints = true;
     GetIPCChannel()->BeginPostponingSends();
   }
 }
 
 } // namespace layers
 } // namespace mozilla
--- a/gfx/layers/ipc/CompositorBridgeChild.h
+++ b/gfx/layers/ipc/CompositorBridgeChild.h
@@ -382,17 +382,17 @@ private:
   size_t mOutstandingAsyncPaints;
 
   // Whether we are waiting for an async paint end transaction
   bool mOutstandingAsyncEndTransaction;
 
   // True if this CompositorBridge is currently delaying its messages until the
   // paint thread completes. This is R/W on both the main and paint threads, and
   // must be accessed within the paint lock.
-  bool mIsWaitingForPaint;
+  bool mIsDelayingForAsyncPaints;
 
   uintptr_t mSlowFlushCount;
   uintptr_t mTotalFlushCount;
 };
 
 } // namespace layers
 } // namespace mozilla
 
--- a/gfx/layers/wr/WebRenderBridgeChild.cpp
+++ b/gfx/layers/wr/WebRenderBridgeChild.cpp
@@ -241,34 +241,32 @@ WebRenderBridgeChild::DeallocExternalIma
   if (mDestroyed) {
     // This can happen if the IPC connection was torn down, because, e.g.
     // the GPU process died.
     return;
   }
   SendRemoveExternalImageId(aImageId);
 }
 
-struct FontFileData
+struct FontFileDataSink
 {
-  wr::ByteBuffer mFontBuffer;
-  uint32_t mFontIndex;
+  wr::FontKey* mFontKey;
+  WebRenderBridgeChild* mWrBridge;
+  wr::IpcResourceUpdateQueue* mResources;
 };
 
 static void
 WriteFontFileData(const uint8_t* aData, uint32_t aLength, uint32_t aIndex,
                   void* aBaton)
 {
-  FontFileData* data = static_cast<FontFileData*>(aBaton);
+  FontFileDataSink* sink = static_cast<FontFileDataSink*>(aBaton);
 
-  if (!data->mFontBuffer.Allocate(aLength)) {
-    return;
-  }
-  memcpy(data->mFontBuffer.mData, aData, aLength);
+  *sink->mFontKey = sink->mWrBridge->GetNextFontKey();
 
-  data->mFontIndex = aIndex;
+  sink->mResources->AddRawFont(*sink->mFontKey, Range<uint8_t>(const_cast<uint8_t*>(aData), aLength), aIndex);
 }
 
 void
 WebRenderBridgeChild::PushGlyphs(wr::DisplayListBuilder& aBuilder, const nsTArray<wr::GlyphInstance>& aGlyphs,
                                  gfx::ScaledFont* aFont, const wr::ColorF& aColor, const StackingContextHelper& aSc,
                                  const wr::LayerRect& aBounds, const wr::LayerRect& aClip, bool aBackfaceVisible)
 {
   MOZ_ASSERT(aFont);
@@ -301,32 +299,25 @@ WebRenderBridgeChild::GetFontKeyForScale
 
   RefPtr<gfx::UnscaledFont> unscaled = aScaledFont->GetUnscaledFont();
   MOZ_ASSERT(unscaled);
 
   wr::IpcResourceUpdateQueue resources(GetShmemAllocator());
 
   wr::FontKey fontKey = { wr::IdNamespace { 0 }, 0};
   if (!mFontKeys.Get(unscaled, &fontKey)) {
-    FontFileData data;
-    if (!unscaled->GetFontFileData(WriteFontFileData, &data) ||
-        !data.mFontBuffer.mData) {
+    FontFileDataSink sink = { &fontKey, this, &resources };
+    if (!unscaled->GetFontFileData(WriteFontFileData, &sink)) {
       return instanceKey;
     }
 
-    fontKey.mNamespace = GetNamespace();
-    fontKey.mHandle = GetNextResourceId();
-
-    resources.AddRawFont(fontKey, data.mFontBuffer.AsSlice(), data.mFontIndex);
-
     mFontKeys.Put(unscaled, fontKey);
   }
 
-  instanceKey.mNamespace = GetNamespace();
-  instanceKey.mHandle = GetNextResourceId();
+  instanceKey = GetNextFontInstanceKey();
 
   Maybe<wr::FontInstanceOptions> options;
   Maybe<wr::FontInstancePlatformOptions> platformOptions;
   std::vector<FontVariation> variations;
   aScaledFont->GetWRFontInstanceOptions(&options, &platformOptions, &variations);
 
   resources.AddFontInstance(instanceKey, fontKey, aScaledFont->GetSize(),
                             options.ptrOr(nullptr), platformOptions.ptrOr(nullptr),
--- a/gfx/layers/wr/WebRenderBridgeChild.h
+++ b/gfx/layers/wr/WebRenderBridgeChild.h
@@ -107,16 +107,26 @@ public:
 
   uint32_t GetNextResourceId() { return ++mResourceId; }
   wr::IdNamespace GetNamespace() { return mIdNamespace; }
   void SetNamespace(wr::IdNamespace aIdNamespace)
   {
     mIdNamespace = aIdNamespace;
   }
 
+  wr::FontKey GetNextFontKey()
+  {
+    return wr::FontKey { GetNamespace(), GetNextResourceId() };
+  }
+
+  wr::FontInstanceKey GetNextFontInstanceKey()
+  {
+    return wr::FontInstanceKey { GetNamespace(), GetNextResourceId() };
+  }
+
   wr::WrImageKey GetNextImageKey()
   {
     return wr::WrImageKey{ GetNamespace(), GetNextResourceId() };
   }
 
   void PushGlyphs(wr::DisplayListBuilder& aBuilder, const nsTArray<wr::GlyphInstance>& aGlyphs,
                   gfx::ScaledFont* aFont, const wr::ColorF& aColor,
                   const StackingContextHelper& aSc,
--- a/gfx/thebes/gfxFontUtils.h
+++ b/gfx/thebes/gfxFontUtils.h
@@ -898,18 +898,22 @@ public:
     DecodeFontName(const char *aBuf, int32_t aLength, 
                    uint32_t aPlatformCode, uint32_t aScriptCode,
                    uint32_t aLangCode, nsAString& dest);
 
     static inline bool IsJoinCauser(uint32_t ch) {
         return (ch == 0x200D);
     }
 
+    // We treat Combining Grapheme Joiner (U+034F) together with the join
+    // controls (ZWJ, ZWNJ) here, because (like them) it is an invisible
+    // char that will be handled by the shaper even if not explicitly
+    // supported by the font. (See bug 1408366.)
     static inline bool IsJoinControl(uint32_t ch) {
-        return (ch == 0x200C || ch == 0x200D);
+        return (ch == 0x200C || ch == 0x200D || ch == 0x034f);
     }
 
     enum {
         kUnicodeVS1 = 0xFE00,
         kUnicodeVS16 = 0xFE0F,
         kUnicodeVS17 = 0xE0100,
         kUnicodeVS256 = 0xE01EF
     };
--- a/js/ipc/JavaScriptParent.cpp
+++ b/js/ipc/JavaScriptParent.cpp
@@ -100,17 +100,17 @@ JavaScriptParent::allowMessage(JSContext
     // warn. If it is marked as compatible, then we check the
     // ForbidCPOWsInCompatibleAddon; see the comment there.
 
     MessageChannel* channel = GetIPCChannel();
     bool isSafe = channel->IsInTransaction();
 
     bool warn = !isSafe;
     nsIGlobalObject* global = dom::GetIncumbentGlobal();
-    JSObject* jsGlobal = global ? global->GetGlobalJSObject() : nullptr;
+    JS::Rooted<JSObject*> jsGlobal(cx, global ? global->GetGlobalJSObject() : nullptr);
     if (jsGlobal) {
         JSAutoCompartment ac(cx, jsGlobal);
         JSAddonId* addonId = JS::AddonIdOfObject(jsGlobal);
 
         if (!xpc::CompartmentPrivate::Get(jsGlobal)->allowCPOWs) {
             if (!addonId && ForbidUnsafeBrowserCPOWs() && !isSafe) {
                 Telemetry::Accumulate(Telemetry::BROWSER_SHIM_USAGE_BLOCKED, 1);
                 JS_ReportErrorASCII(cx, "unsafe CPOW usage forbidden");
--- a/js/src/devtools/rootAnalysis/annotations.js
+++ b/js/src/devtools/rootAnalysis/annotations.js
@@ -220,16 +220,18 @@ var ignoreFunctions = {
     "float64 JS_GetCurrentEmbedderTime()" : true,
 
     "uint64 js::TenuringTracer::moveObjectToTenured(JSObject*, JSObject*, int32)" : true,
     "uint32 js::TenuringTracer::moveObjectToTenured(JSObject*, JSObject*, int32)" : true,
     "void js::Nursery::freeMallocedBuffers()" : true,
 
     "void js::AutoEnterOOMUnsafeRegion::crash(uint64, int8*)" : true,
 
+    "void mozilla::dom::workers::WorkerPrivate::AssertIsOnWorkerThread() const" : true,
+
     // It would be cool to somehow annotate that nsTHashtable<T> will use
     // nsTHashtable<T>::s_MatchEntry for its matchEntry function pointer, but
     // there is no mechanism for that. So we will just annotate a particularly
     // troublesome logging-related usage.
     "EntryType* nsTHashtable<EntryType>::PutEntry(nsTHashtable<EntryType>::KeyType, const fallible_t&) [with EntryType = nsBaseHashtableET<nsCharPtrHashKey, nsAutoPtr<mozilla::LogModule> >; nsTHashtable<EntryType>::KeyType = const char*; nsTHashtable<EntryType>::fallible_t = mozilla::fallible_t]" : true,
     "EntryType* nsTHashtable<EntryType>::GetEntry(nsTHashtable<EntryType>::KeyType) const [with EntryType = nsBaseHashtableET<nsCharPtrHashKey, nsAutoPtr<mozilla::LogModule> >; nsTHashtable<EntryType>::KeyType = const char*]" : true,
     "EntryType* nsTHashtable<EntryType>::PutEntry(nsTHashtable<EntryType>::KeyType) [with EntryType = nsBaseHashtableET<nsPtrHashKey<const mozilla::BlockingResourceBase>, nsAutoPtr<mozilla::DeadlockDetector<mozilla::BlockingResourceBase>::OrderingEntry> >; nsTHashtable<EntryType>::KeyType = const mozilla::BlockingResourceBase*]" : true,
     "EntryType* nsTHashtable<EntryType>::GetEntry(nsTHashtable<EntryType>::KeyType) const [with EntryType = nsBaseHashtableET<nsPtrHashKey<const mozilla::BlockingResourceBase>, nsAutoPtr<mozilla::DeadlockDetector<mozilla::BlockingResourceBase>::OrderingEntry> >; nsTHashtable<EntryType>::KeyType = const mozilla::BlockingResourceBase*]" : true,
@@ -395,16 +397,18 @@ function isOverridableField(initialCSU, 
     if (field == 'IsOnCurrentThread')
         return false;
     if (field == 'GetNativeContext')
         return false;
     if (field == "GetGlobalJSObject")
         return false;
     if (field == "GetIsMainThread")
         return false;
+    if (field == "GetThreadFromPRThread")
+        return false;
     if (initialCSU == 'nsIXPConnectJSObjectHolder' && field == 'GetJSObject')
         return false;
     if (initialCSU == 'nsIXPConnect' && field == 'GetSafeJSContext')
         return false;
 
     // nsIScriptSecurityManager is not [builtinclass], but smaug says "the
     // interface definitely should be builtinclass", which is good enough.
     if (initialCSU == 'nsIScriptSecurityManager' && field == 'IsSystemPrincipal')
--- a/js/src/ds/LifoAlloc.h
+++ b/js/src/ds/LifoAlloc.h
@@ -211,37 +211,42 @@ AlignPtr(uint8_t* orig) {
 // This structure is only move-able, but not copyable.
 class BumpChunk : public SingleLinkedListElement<BumpChunk>
 {
   private:
     // Pointer to the last byte allocated in this chunk.
     uint8_t* bump_;
     // Pointer to the last byte available in this chunk.
     const uint8_t* capacity_;
+
+#ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED
     // Magic number used to check against poisoned values.
     const uintptr_t magic_;
+    static constexpr uintptr_t magicNumber =
+        sizeof(uintptr_t) == 4 ? uintptr_t(0x4c69666f) : uintptr_t(0x4c69666f42756d70);
+#endif
 
     // Byte used for poisoning unused memory after releasing memory.
     static constexpr int undefinedChunkMemory = 0xcd;
-    static constexpr uintptr_t magicNumber =
-        sizeof(uintptr_t) == 4 ? uintptr_t(0x4c69666f) : uintptr_t(0x4c69666f42756d70);
 
     void assertInvariants() {
         MOZ_DIAGNOSTIC_ASSERT(magic_ == magicNumber);
         MOZ_ASSERT(begin() <= end());
         MOZ_ASSERT(end() <= capacity_);
     }
 
     BumpChunk& operator=(const BumpChunk&) = delete;
     BumpChunk(const BumpChunk&) = delete;
 
     explicit BumpChunk(uintptr_t capacity)
       : bump_(begin()),
-        capacity_(base() + capacity),
-        magic_(magicNumber)
+        capacity_(base() + capacity)
+#ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED
+      , magic_(magicNumber)
+#endif
     {
         // We cannot bake this value inside the BumpChunk class, because
         // sizeof(BumpChunk) can only be computed after the closing brace of the
         // BumpChunk class, or within one of its methods. As a work-around, the
         // reservedSpace value is baked in, and we check that it indeed matches
         // with the space taken by the data of the BumpChunk class, and the
         // alignment of a pointer.
         MOZ_ASSERT(BumpChunk::reservedSpace == AlignBytes(sizeof(BumpChunk), LIFO_ALLOC_ALIGN),
--- a/js/src/jit/OptimizationTracking.cpp
+++ b/js/src/jit/OptimizationTracking.cpp
@@ -140,17 +140,17 @@ SpewTempOptimizationTypeInfoVector(JitSp
                                    const char* indent = nullptr)
 {
 #ifdef JS_JITSPEW
     for (const OptimizationTypeInfo* t = types->begin(); t != types->end(); t++) {
         JitSpewStart(channel, "   %s%s of type %s, type set",
                      indent ? indent : "",
                      TrackedTypeSiteString(t->site()), StringFromMIRType(t->mirType()));
         for (uint32_t i = 0; i < t->types().length(); i++)
-            JitSpewCont(channel, " %s", TypeSet::TypeString(t->types()[i]));
+            JitSpewCont(channel, " %s", TypeSet::TypeString(t->types()[i]).get());
         JitSpewFin(channel);
     }
 #endif
 }
 
 void
 SpewTempOptimizationAttemptsVector(JitSpewChannel channel,
                                    const TempOptimizationAttemptsVector* attempts,
@@ -867,44 +867,44 @@ InterpretedFunctionFilenameAndLineNumber
 }
 
 static void
 SpewConstructor(TypeSet::Type ty, JSFunction* constructor)
 {
 #ifdef JS_JITSPEW
     if (!constructor->isInterpreted()) {
         JitSpew(JitSpew_OptimizationTrackingExtended, "   Unique type %s has native constructor",
-                TypeSet::TypeString(ty));
+                TypeSet::TypeString(ty).get());
         return;
     }
 
     char buf[512];
     if (constructor->displayAtom())
         PutEscapedString(buf, 512, constructor->displayAtom(), 0);
     else
         snprintf(buf, mozilla::ArrayLength(buf), "??");
 
     const char* filename;
     Maybe<unsigned> lineno;
     InterpretedFunctionFilenameAndLineNumber(constructor, &filename, &lineno);
 
     JitSpew(JitSpew_OptimizationTrackingExtended, "   Unique type %s has constructor %s (%s:%u)",
-            TypeSet::TypeString(ty), buf, filename, lineno.isSome() ? *lineno : 0);
+            TypeSet::TypeString(ty).get(), buf, filename, lineno.isSome() ? *lineno : 0);
 #endif
 }
 
 static void
 SpewAllocationSite(TypeSet::Type ty, JSScript* script, uint32_t offset)
 {
 #ifdef JS_JITSPEW
     if (!JitSpewEnabled(JitSpew_OptimizationTrackingExtended))
         return;
 
     JitSpew(JitSpew_OptimizationTrackingExtended, "   Unique type %s has alloc site %s:%u",
-            TypeSet::TypeString(ty), script->filename(),
+            TypeSet::TypeString(ty).get(), script->filename(),
             PCToLineNumber(script, script->offsetToPC(offset)));
 #endif
 }
 
 bool
 jit::WriteIonTrackedOptimizationsTable(JSContext* cx, CompactBufferWriter& writer,
                                        const NativeToTrackedOptimizations* start,
                                        const NativeToTrackedOptimizations* end,
--- a/js/src/jit/none/MacroAssembler-none.h
+++ b/js/src/jit/none/MacroAssembler-none.h
@@ -75,16 +75,17 @@ static constexpr Register64 ReturnReg64(
 #else
 #error "Bad architecture"
 #endif
 
 static constexpr Register ABINonArgReg0 { Registers::invalid_reg };
 static constexpr Register ABINonArgReg1 { Registers::invalid_reg };
 static constexpr Register ABINonArgReturnReg0 { Registers::invalid_reg };
 static constexpr Register ABINonArgReturnReg1 { Registers::invalid_reg };
+static constexpr Register NativeABIPrologueClobberable { Registers::invalid_reg };
 
 static constexpr Register WasmTableCallScratchReg { Registers::invalid_reg };
 static constexpr Register WasmTableCallSigReg { Registers::invalid_reg };
 static constexpr Register WasmTableCallIndexReg { Registers::invalid_reg };
 static constexpr Register WasmTlsReg { Registers::invalid_reg };
 
 static constexpr uint32_t ABIStackAlignment = 4;
 static constexpr uint32_t CodeAlignment = 4;
--- a/js/src/jsgc.cpp
+++ b/js/src/jsgc.cpp
@@ -6970,16 +6970,41 @@ gc::IsIncrementalGCUnsafe(JSRuntime* rt)
     MOZ_ASSERT(!TlsContext.get()->suppressGC);
 
     if (!rt->gc.isIncrementalGCAllowed())
         return gc::AbortReason::IncrementalDisabled;
 
     return gc::AbortReason::None;
 }
 
+static inline void
+CheckZoneIsScheduled(Zone* zone, JS::gcreason::Reason reason, const char* trigger)
+{
+#ifdef DEBUG
+    if (zone->isGCScheduled())
+        return;
+
+    fprintf(stderr,
+            "CheckZoneIsScheduled: Zone %p not scheduled as expected in %s GC for %s trigger\n",
+            zone,
+            JS::gcreason::ExplainReason(reason),
+            trigger);
+    JSRuntime* rt = zone->runtimeFromActiveCooperatingThread();
+    for (ZonesIter zone(rt, WithAtoms); !zone.done(); zone.next()) {
+        fprintf(stderr,
+                "  Zone %p:%s%s\n",
+                zone.get(),
+                zone->isAtomsZone() ? " atoms" : "",
+                zone->isGCScheduled() ? " scheduled" : "");
+    }
+    fflush(stderr);
+    MOZ_CRASH("Zone not scheduled");
+#endif
+}
+
 GCRuntime::IncrementalResult
 GCRuntime::budgetIncrementalGC(bool nonincrementalByAPI, JS::gcreason::Reason reason,
                                SliceBudget& budget, AutoLockForExclusiveAccess& lock)
 {
     if (nonincrementalByAPI) {
         stats().nonincremental(gc::AbortReason::NonIncrementalRequested);
         budget.makeUnlimited();
 
@@ -7019,23 +7044,23 @@ GCRuntime::budgetIncrementalGC(bool noni
     }
 
     bool reset = false;
     for (ZonesIter zone(rt, WithAtoms); !zone.done(); zone.next()) {
         if (!zone->canCollect())
             continue;
 
         if (zone->usage.gcBytes() >= zone->threshold.gcTriggerBytes()) {
-            MOZ_ASSERT(zone->isGCScheduled());
+            CheckZoneIsScheduled(zone, reason, "GC bytes");
             budget.makeUnlimited();
             stats().nonincremental(AbortReason::GCBytesTrigger);
         }
 
         if (zone->isTooMuchMalloc()) {
-            MOZ_ASSERT(zone->isGCScheduled());
+            CheckZoneIsScheduled(zone, reason, "malloc bytes");
             budget.makeUnlimited();
             stats().nonincremental(AbortReason::MallocBytesTrigger);
         }
 
         if (isIncrementalGCInProgress() && zone->isGCScheduled() != zone->wasGCStarted())
             reset = true;
     }
 
--- a/js/src/shell/js.cpp
+++ b/js/src/shell/js.cpp
@@ -286,19 +286,17 @@ OffThreadState::waitUntilDone(JSContext*
     return holdToken;
 }
 
 struct ShellCompartmentPrivate {
     JS::Heap<JSObject*> grayRoot;
 };
 
 struct MOZ_STACK_CLASS EnvironmentPreparer : public js::ScriptEnvironmentPreparer {
-    JSContext* cx;
     explicit EnvironmentPreparer(JSContext* cx)
-      : cx(cx)
     {
         js::SetScriptEnvironmentPreparer(cx, this);
     }
     void invoke(JS::HandleObject scope, Closure& closure) override;
 };
 
 // Shell state set once at startup.
 static bool enableCodeCoverage = false;
@@ -601,16 +599,17 @@ SkipUTF8BOM(FILE* file)
         ungetc(ch2, file);
     if (ch1 != EOF)
         ungetc(ch1, file);
 }
 
 void
 EnvironmentPreparer::invoke(HandleObject scope, Closure& closure)
 {
+    JSContext* cx = TlsContext.get();
     MOZ_ASSERT(!JS_IsExceptionPending(cx));
 
     AutoCompartment ac(cx, scope);
     AutoReportException are(cx);
     if (!closure(cx))
         return;
 }
 
--- a/js/src/vm/StructuredClone.cpp
+++ b/js/src/vm/StructuredClone.cpp
@@ -1213,21 +1213,21 @@ JSStructuredCloneWriter::writeDataView(H
         return false;
 
     return out.write(view->byteOffset());
 }
 
 bool
 JSStructuredCloneWriter::writeArrayBuffer(HandleObject obj)
 {
-    ArrayBufferObject& buffer = CheckedUnwrap(obj)->as<ArrayBufferObject>();
-    JSAutoCompartment ac(context(), &buffer);
-
-    return out.writePair(SCTAG_ARRAY_BUFFER_OBJECT, buffer.byteLength()) &&
-           out.writeBytes(buffer.dataPointer(), buffer.byteLength());
+    Rooted<ArrayBufferObject*> buffer(context(), &CheckedUnwrap(obj)->as<ArrayBufferObject>());
+    JSAutoCompartment ac(context(), buffer);
+
+    return out.writePair(SCTAG_ARRAY_BUFFER_OBJECT, buffer->byteLength()) &&
+           out.writeBytes(buffer->dataPointer(), buffer->byteLength());
 }
 
 bool
 JSStructuredCloneWriter::writeSharedArrayBuffer(HandleObject obj)
 {
     if (!cloneDataPolicy.isSharedArrayBufferAllowed()) {
         JS_ReportErrorNumberASCII(context(), GetErrorMessage, nullptr, JSMSG_SC_NOT_CLONABLE,
                                   "SharedArrayBuffer");
--- a/js/src/vm/TypeInference-inl.h
+++ b/js/src/vm/TypeInference-inl.h
@@ -641,17 +641,17 @@ TypeScript::SetThis(JSContext* cx, JSScr
     StackTypeSet* types = ThisTypes(script);
     if (!types)
         return;
 
     if (!types->hasType(type)) {
         AutoEnterAnalysis enter(cx);
 
         InferSpew(ISpewOps, "externalType: setThis %p: %s",
-                  script, TypeSet::TypeString(type));
+                  script, TypeSet::TypeString(type).get());
         types->addType(cx, type);
     }
 }
 
 /* static */ inline void
 TypeScript::SetThis(JSContext* cx, JSScript* script, const js::Value& value)
 {
     SetThis(cx, script, TypeSet::GetValueType(value));
@@ -665,17 +665,17 @@ TypeScript::SetArgument(JSContext* cx, J
     StackTypeSet* types = ArgTypes(script, arg);
     if (!types)
         return;
 
     if (!types->hasType(type)) {
         AutoEnterAnalysis enter(cx);
 
         InferSpew(ISpewOps, "externalType: setArg %p %u: %s",
-                  script, arg, TypeSet::TypeString(type));
+                  script, arg, TypeSet::TypeString(type).get());
         types->addType(cx, type);
     }
 }
 
 /* static */ inline void
 TypeScript::SetArgument(JSContext* cx, JSScript* script, unsigned arg, const js::Value& value)
 {
     SetArgument(cx, script, arg, TypeSet::GetValueType(value));
--- a/js/src/vm/TypeInference.cpp
+++ b/js/src/vm/TypeInference.cpp
@@ -119,38 +119,43 @@ TypeSet::NonObjectTypeString(TypeSet::Ty
     }
     if (type.isUnknown())
         return "unknown";
 
     MOZ_ASSERT(type.isAnyObject());
     return "object";
 }
 
-/* static */ const char*
+static UniqueChars MakeStringCopy(const char* s)
+{
+    AutoEnterOOMUnsafeRegion oomUnsafe;
+    char* copy = strdup(s);
+    if (!copy)
+        oomUnsafe.crash("Could not copy string");
+    return UniqueChars(copy);
+}
+
+/* static */ UniqueChars
 TypeSet::TypeString(TypeSet::Type type)
 {
     if (type.isPrimitive() || type.isUnknown() || type.isAnyObject())
-        return NonObjectTypeString(type);
-
-    static char bufs[4][40];
-    static unsigned which = 0;
-    which = (which + 1) & 3;
-
+        return MakeStringCopy(NonObjectTypeString(type));
+
+    char buf[100];
     if (type.isSingleton()) {
         JSObject* singleton = type.singletonNoBarrier();
-        snprintf(bufs[which], 40, "<%s %#" PRIxPTR ">",
-                 singleton->getClass()->name, uintptr_t(singleton));
+        SprintfLiteral(buf, "<%s %#" PRIxPTR ">", singleton->getClass()->name, uintptr_t(singleton));
     } else {
-        snprintf(bufs[which], 40, "[%s * %#" PRIxPTR "]", type.groupNoBarrier()->clasp()->name, uintptr_t(type.groupNoBarrier()));
+        SprintfLiteral(buf, "[%s * %#" PRIxPTR "]", type.groupNoBarrier()->clasp()->name, uintptr_t(type.groupNoBarrier()));
     }
 
-    return bufs[which];
+    return MakeStringCopy(buf);
 }
 
-/* static */ const char*
+/* static */ UniqueChars
 TypeSet::ObjectGroupString(ObjectGroup* group)
 {
     return TypeString(TypeSet::ObjectType(group));
 }
 
 #ifdef DEBUG
 
 bool
@@ -298,18 +303,18 @@ js::ObjectGroupHasProperty(JSContext* cx
             }
             JSObject* obj = &value.toObject();
             if (!obj->hasLazyGroup() && obj->group()->maybeOriginalUnboxedGroup())
                 return true;
         }
 
         if (!types->hasType(type)) {
             TypeFailure(cx, "Missing type in object %s %s: %s",
-                        TypeSet::ObjectGroupString(group), TypeIdString(id),
-                        TypeSet::TypeString(type));
+                        TypeSet::ObjectGroupString(group).get(), TypeIdString(id),
+                        TypeSet::TypeString(type).get());
         }
     }
     return true;
 }
 
 #endif
 
 
@@ -699,17 +704,17 @@ ConstraintTypeSet::addType(JSContext* cx
 
     if (type.isObjectUnchecked() && unknownObject())
         type = AnyObjectType();
 
     postWriteBarrier(cx, type);
 
     InferSpew(ISpewOps, "addType: %sT%p%s %s",
               InferSpewColor(this), this, InferSpewColorReset(),
-              TypeString(type));
+              TypeString(type).get());
 
     /* Propagate the type to all constraints. */
     if (!cx->helperThread()) {
         TypeConstraint* constraint = constraintList();
         while (constraint) {
             constraint->newType(cx, this, type);
             constraint = constraint->next();
         }
@@ -764,17 +769,17 @@ TypeSet::print(FILE* fp)
     uint32_t objectCount = baseObjectCount();
     if (objectCount) {
         fprintf(fp, " object[%u]", objectCount);
 
         unsigned count = getObjectCount();
         for (unsigned i = 0; i < count; i++) {
             ObjectKey* key = getObject(i);
             if (key)
-                fprintf(fp, " %s", TypeString(ObjectType(key)));
+                fprintf(fp, " %s", TypeString(ObjectType(key)).get());
         }
     }
 
     if (fromDebugger)
         fprintf(fp, "\n");
 }
 
 /* static */ void
@@ -2660,27 +2665,28 @@ UpdatePropertyType(JSContext* cx, HeapTy
             types->postWriteBarrier(cx, type);
         }
 
         if (indexed || shape->hadOverwrite()) {
             types->setNonConstantProperty(cx);
         } else {
             InferSpew(ISpewOps, "typeSet: %sT%p%s property %s %s - setConstant",
                       InferSpewColor(types), types, InferSpewColorReset(),
-                      TypeSet::ObjectGroupString(obj->group()), TypeIdString(shape->propid()));
+                      TypeSet::ObjectGroupString(obj->group()).get(),
+                      TypeIdString(shape->propid()));
         }
     }
 }
 
 void
 ObjectGroup::updateNewPropertyTypes(JSContext* cx, JSObject* objArg, jsid id, HeapTypeSet* types)
 {
     InferSpew(ISpewOps, "typeSet: %sT%p%s property %s %s",
               InferSpewColor(types), types, InferSpewColorReset(),
-              TypeSet::ObjectGroupString(this), TypeIdString(id));
+              TypeSet::ObjectGroupString(this).get(), TypeIdString(id));
 
     MOZ_ASSERT_IF(objArg, objArg->group() == this);
     MOZ_ASSERT_IF(singleton(), objArg);
 
     if (!singleton() || !objArg->isNative()) {
         types->setNonConstantProperty(cx);
         return;
     }
@@ -2795,25 +2801,28 @@ js::AddTypePropertyId(JSContext* cx, Obj
 
     HeapTypeSet* types = group->getProperty(cx, obj, id);
     if (!types)
         return;
 
     // Clear any constant flag if it exists.
     if (!types->empty() && !types->nonConstantProperty()) {
         InferSpew(ISpewOps, "constantMutated: %sT%p%s %s",
-                  InferSpewColor(types), types, InferSpewColorReset(), TypeSet::TypeString(type));
+                  InferSpewColor(types), types, InferSpewColorReset(),
+                  TypeSet::TypeString(type).get());
         types->setNonConstantProperty(cx);
     }
 
     if (types->hasType(type))
         return;
 
     InferSpew(ISpewOps, "externalType: property %s %s: %s",
-              TypeSet::ObjectGroupString(group), TypeIdString(id), TypeSet::TypeString(type));
+              TypeSet::ObjectGroupString(group).get(),
+              TypeIdString(id),
+              TypeSet::TypeString(type).get());
     types->addType(cx, type);
 
     // If this addType caused the type set to be marked as containing any
     // object, make sure that is reflected in other type sets the addType is
     // propagated to below.
     if (type.isObjectUnchecked() && types->unknownObject())
         type = TypeSet::AnyObjectType();
 
@@ -2894,17 +2903,17 @@ ObjectGroup::setFlags(JSContext* cx, Obj
 
     if (hasAllFlags(flags))
         return;
 
     AutoEnterAnalysis enter(cx);
 
     addFlags(flags);
 
-    InferSpew(ISpewOps, "%s: setFlags 0x%x", TypeSet::ObjectGroupString(this), flags);
+    InferSpew(ISpewOps, "%s: setFlags 0x%x", TypeSet::ObjectGroupString(this).get(), flags);
 
     ObjectStateChange(cx, this, false);
 
     // Propagate flag changes from partially to fully initialized groups for the
     // acquired properties analysis.
     if (newScript() && newScript()->initializedGroup())
         newScript()->initializedGroup()->setFlags(cx, flags);
 
@@ -2918,17 +2927,17 @@ ObjectGroup::setFlags(JSContext* cx, Obj
 void
 ObjectGroup::markUnknown(JSContext* cx)
 {
     AutoEnterAnalysis enter(cx);
 
     MOZ_ASSERT(cx->zone()->types.activeAnalysis);
     MOZ_ASSERT(!unknownProperties());
 
-    InferSpew(ISpewOps, "UnknownProperties: %s", TypeSet::ObjectGroupString(this));
+    InferSpew(ISpewOps, "UnknownProperties: %s", TypeSet::ObjectGroupString(this).get());
 
     clearNewScript(cx);
     ObjectStateChange(cx, this, true);
 
     /*
      * Existing constraints may have already been added to this object, which we need
      * to do the right thing for. We can't ensure that we will mark all unknown
      * objects before they have been accessed, as the __proto__ of a known object
@@ -3065,19 +3074,19 @@ ObjectGroup::clearNewScript(JSContext* c
     markStateChange(cx);
 }
 
 void
 ObjectGroup::print()
 {
     TaggedProto tagged(proto());
     fprintf(stderr, "%s : %s",
-            TypeSet::ObjectGroupString(this),
+            TypeSet::ObjectGroupString(this).get(),
             tagged.isObject()
-            ? TypeSet::TypeString(TypeSet::ObjectType(tagged.toObject()))
+            ? TypeSet::TypeString(TypeSet::ObjectType(tagged.toObject())).get()
             : tagged.isDynamic()
             ? "(dynamic)"
             : "(null)");
 
     if (unknownProperties()) {
         fprintf(stderr, " unknown");
     } else {
         if (!hasAnyFlags(OBJECT_FLAG_SPARSE_INDEXES))
@@ -3320,33 +3329,33 @@ js::TypeMonitorResult(JSContext* cx, JSS
 
     AutoEnterAnalysis enter(cx);
 
     StackTypeSet* types = TypeScript::BytecodeTypes(script, pc);
     if (types->hasType(type))
         return;
 
     InferSpew(ISpewOps, "bytecodeType: %p %05zu: %s",
-              script, script->pcToOffset(pc), TypeSet::TypeString(type));
+              script, script->pcToOffset(pc), TypeSet::TypeString(type).get());
     types->addType(cx, type);
 }
 
 void
 js::TypeMonitorResult(JSContext* cx, JSScript* script, jsbytecode* pc, StackTypeSet* types,
                       TypeSet::Type type)
 {
     assertSameCompartment(cx, script, type);
 
     AutoEnterAnalysis enter(cx);
 
     MOZ_ASSERT(types == TypeScript::BytecodeTypes(script, pc));
     MOZ_ASSERT(!types->hasType(type));
 
     InferSpew(ISpewOps, "bytecodeType: %p %05zu: %s",
-              script, script->pcToOffset(pc), TypeSet::TypeString(type));
+              script, script->pcToOffset(pc), TypeSet::TypeString(type).get());
     types->addType(cx, type);
 }
 
 void
 js::TypeMonitorResult(JSContext* cx, JSScript* script, jsbytecode* pc, const js::Value& rval)
 {
     /* Allow the non-TYPESET scenario to simplify stubs used in compound opcodes. */
     if (!(CodeSpec[*pc].format & JOF_TYPESET))
--- a/js/src/vm/TypeInference.h
+++ b/js/src/vm/TypeInference.h
@@ -377,18 +377,18 @@ class TypeSet
     }
 
     static inline Type ObjectType(JSObject* obj);
     static inline Type ObjectType(ObjectGroup* group);
     static inline Type ObjectType(ObjectKey* key);
 
     static const char* NonObjectTypeString(Type type);
 
-    static const char* TypeString(Type type);
-    static const char* ObjectGroupString(ObjectGroup* group);
+    static UniqueChars TypeString(Type type);
+    static UniqueChars ObjectGroupString(ObjectGroup* group);
 
   protected:
     /* Flags for this type set. */
     TypeFlags flags;
 
     /* Possible objects this type set can represent. */
     ObjectKey** objectSet;
 
--- a/layout/painting/nsDisplayList.cpp
+++ b/layout/painting/nsDisplayList.cpp
@@ -2181,17 +2181,17 @@ already_AddRefed<LayerManager> nsDisplay
     }
 
     aBuilder->SetIsCompositingCheap(temp);
     if (document && widgetTransaction) {
       TriggerPendingAnimations(document, layerManager->GetAnimationReadyTime());
     }
 
     if (presContext->RefreshDriver()->HasScheduleFlush()) {
-      presContext->NotifyInvalidation(layerManager->GetLastTransactionId(), nsIntRect());
+      presContext->NotifyInvalidation(layerManager->GetLastTransactionId(), frame->GetRect());
     }
 
     return layerManager.forget();
   }
 
   NotifySubDocInvalidationFunc computeInvalidFunc =
     presContext->MayHavePaintEventListenerInSubDocument() ? nsPresContext::NotifySubDocInvalidation : 0;
 
--- a/layout/reftests/svg/reftest.list
+++ b/layout/reftests/svg/reftest.list
@@ -372,17 +372,17 @@ fuzzy-if(webrender,0-2,0-227) == pattern
 # reftest harness.
 # == pseudo-classes-02.svg pseudo-classes-02-ref.svg
 
 == radialGradient-basic-01.svg pass.svg
 == radialGradient-basic-02.svg pass.svg
 fuzzy-if(cocoaWidget,4,15982) fuzzy-if(winWidget,4,92) fuzzy-if(skiaContent,4,60) == radialGradient-basic-03.svg radialGradient-basic-03-ref.svg
 == radialGradient-basic-04.svg pass.svg
 == radialGradient-fr-01.svg pass.svg
-fuzzy(1,3235) fuzzy-if(winWidget,1,6704) fuzzy-if(winWidget&&stylo,1,6711) == radialGradient-fr-02.svg radialGradient-fr-02-ref.svg
+fuzzy(1,3235) fuzzy-if(winWidget,1,6711) == radialGradient-fr-02.svg radialGradient-fr-02-ref.svg
 
 fuzzy-if(skiaContent,1,3600) == rect-01.svg pass.svg
 == rect-02.svg pass.svg
 == rect-03.svg pass.svg
 == rect-04.svg pass.svg
 == rect-with-rx-and-ry-01.svg pass.svg
 == rect-with-rx-or-ry-01.svg rect-with-rx-or-ry-01-ref.svg
 
--- a/media/webrtc/signaling/src/common/browser_logging/CSFLog.cpp
+++ b/media/webrtc/signaling/src/common/browser_logging/CSFLog.cpp
@@ -75,8 +75,13 @@ void CSFLog( CSFLogLevel priority, const
 {
 	va_list ap;
   va_start(ap, format);
 
   CSFLogV(priority, sourceFile, sourceLine, tag, format, ap);
   va_end(ap);
 }
 
+int CSFLogTestLevel(CSFLogLevel priority)
+{
+  mozilla::LogLevel level = static_cast<mozilla::LogLevel>(priority);
+  return MOZ_LOG_TEST(gSignalingLog, level);
+}
--- a/media/webrtc/signaling/src/common/browser_logging/CSFLog.h
+++ b/media/webrtc/signaling/src/common/browser_logging/CSFLog.h
@@ -33,13 +33,15 @@ extern "C"
 void CSFLog( CSFLogLevel priority, const char* sourceFile, int sourceLine, const char* tag , const char* format, ...)
 #ifdef __GNUC__
   __attribute__ ((format (printf, 5, 6)))
 #endif
 ;
 
 void CSFLogV( CSFLogLevel priority, const char* sourceFile, int sourceLine, const char* tag , const char* format, va_list args);
 
+int CSFLogTestLevel(CSFLogLevel priority);
+
 #ifdef __cplusplus
 }
 #endif
 
 #endif
--- a/media/webrtc/signaling/src/media-conduit/AudioConduit.cpp
+++ b/media/webrtc/signaling/src/media-conduit/AudioConduit.cpp
@@ -28,48 +28,52 @@
 #include "webrtc/system_wrappers/include/clock.h"
 
 #ifdef MOZ_WIDGET_ANDROID
 #include "AndroidJNIWrapper.h"
 #endif
 
 namespace mozilla {
 
-static const char* logTag ="WebrtcAudioSessionConduit";
+static const char* acLogTag ="WebrtcAudioSessionConduit";
+#ifdef LOGTAG
+#undef LOGTAG
+#endif
+#define LOGTAG acLogTag
 
 // 32 bytes is what WebRTC CodecInst expects
 const unsigned int WebrtcAudioConduit::CODEC_PLNAME_SIZE = 32;
 
 /**
  * Factory Method for AudioConduit
  */
 RefPtr<AudioSessionConduit> AudioSessionConduit::Create()
 {
-  CSFLogDebug(logTag,  "%s ", __FUNCTION__);
+  CSFLogDebug(LOGTAG,  "%s ", __FUNCTION__);
   NS_ASSERTION(NS_IsMainThread(), "Only call on main thread");
 
   WebrtcAudioConduit* obj = new WebrtcAudioConduit();
   if(obj->Init() != kMediaConduitNoError)
   {
-    CSFLogError(logTag,  "%s AudioConduit Init Failed ", __FUNCTION__);
+    CSFLogError(LOGTAG,  "%s AudioConduit Init Failed ", __FUNCTION__);
     delete obj;
     return nullptr;
   }
-  CSFLogDebug(logTag,  "%s Successfully created AudioConduit ", __FUNCTION__);
+  CSFLogDebug(LOGTAG,  "%s Successfully created AudioConduit ", __FUNCTION__);
   return obj;
 }
 
 /**
  * Destruction defines for our super-classes
  */
 WebrtcAudioConduit::~WebrtcAudioConduit()
 {
   NS_ASSERTION(NS_IsMainThread(), "Only call on main thread");
 
-  CSFLogDebug(logTag,  "%s ", __FUNCTION__);
+  CSFLogDebug(LOGTAG,  "%s ", __FUNCTION__);
   for(auto & codec : mRecvCodecList)
   {
     delete codec;
   }
 
   // The first one of a pair to be deleted shuts down media for both
   if(mPtrVoEXmedia)
   {
@@ -250,21 +254,21 @@ bool WebrtcAudioConduit::GetRTCPSenderRe
                                           senderInfo.NTPfraction);
     *packetsSent = senderInfo.sendPacketCount;
     *bytesSent = senderInfo.sendOctetCount;
    }
    return result;
  }
 
 bool WebrtcAudioConduit::SetDtmfPayloadType(unsigned char type, int freq) {
-  CSFLogInfo(logTag, "%s : setting dtmf payload %d", __FUNCTION__, (int)type);
+  CSFLogInfo(LOGTAG, "%s : setting dtmf payload %d", __FUNCTION__, (int)type);
 
   int result = mChannelProxy->SetSendTelephoneEventPayloadType(type, freq);
   if (result == -1) {
-    CSFLogError(logTag, "%s Failed call to SetSendTelephoneEventPayloadType(%u, %d)",
+    CSFLogError(LOGTAG, "%s Failed call to SetSendTelephoneEventPayloadType(%u, %d)",
                 __FUNCTION__, type, freq);
   }
   return result != -1;
 }
 
 bool WebrtcAudioConduit::InsertDTMFTone(int channel, int eventCode,
                                         bool outOfBand, int lengthMs,
                                         int attenuationDb) {
@@ -281,152 +285,152 @@ bool WebrtcAudioConduit::InsertDTMFTone(
   return result != -1;
 }
 
 /*
  * WebRTCAudioConduit Implementation
  */
 MediaConduitErrorCode WebrtcAudioConduit::Init()
 {
-  CSFLogDebug(logTag,  "%s this=%p", __FUNCTION__, this);
+  CSFLogDebug(LOGTAG,  "%s this=%p", __FUNCTION__, this);
 
 #ifdef MOZ_WIDGET_ANDROID
     jobject context = jsjni_GetGlobalContextRef();
     // get the JVM
     JavaVM *jvm = jsjni_GetVM();
 
     if (webrtc::VoiceEngine::SetAndroidObjects(jvm, (void*)context) != 0) {
-      CSFLogError(logTag, "%s Unable to set Android objects", __FUNCTION__);
+      CSFLogError(LOGTAG, "%s Unable to set Android objects", __FUNCTION__);
       return kMediaConduitSessionNotInited;
     }
 #endif
 
   // Per WebRTC APIs below function calls return nullptr on failure
   if(!(mVoiceEngine = webrtc::VoiceEngine::Create()))
   {
-    CSFLogError(logTag, "%s Unable to create voice engine", __FUNCTION__);
+    CSFLogError(LOGTAG, "%s Unable to create voice engine", __FUNCTION__);
     return kMediaConduitSessionNotInited;
   }
 
   if(!(mPtrVoEBase = VoEBase::GetInterface(mVoiceEngine)))
   {
-    CSFLogError(logTag, "%s Unable to initialize VoEBase", __FUNCTION__);
+    CSFLogError(LOGTAG, "%s Unable to initialize VoEBase", __FUNCTION__);
     return kMediaConduitSessionNotInited;
   }
 
   // init the engine with our audio device layer
   if(mPtrVoEBase->Init() == -1)
   {
-    CSFLogError(logTag, "%s VoiceEngine Base Not Initialized", __FUNCTION__);
+    CSFLogError(LOGTAG, "%s VoiceEngine Base Not Initialized", __FUNCTION__);
     return kMediaConduitSessionNotInited;
   }
 
   if(!(mPtrVoENetwork = VoENetwork::GetInterface(mVoiceEngine)))
   {
-    CSFLogError(logTag, "%s Unable to initialize VoENetwork", __FUNCTION__);
+    CSFLogError(LOGTAG, "%s Unable to initialize VoENetwork", __FUNCTION__);
     return kMediaConduitSessionNotInited;
   }
 
   if(!(mPtrVoECodec = VoECodec::GetInterface(mVoiceEngine)))
   {
-    CSFLogError(logTag, "%s Unable to initialize VoEBCodec", __FUNCTION__);
+    CSFLogError(LOGTAG, "%s Unable to initialize VoEBCodec", __FUNCTION__);
     return kMediaConduitSessionNotInited;
   }
 
   if(!(mPtrVoEProcessing = VoEAudioProcessing::GetInterface(mVoiceEngine)))
   {
-    CSFLogError(logTag, "%s Unable to initialize VoEProcessing", __FUNCTION__);
+    CSFLogError(LOGTAG, "%s Unable to initialize VoEProcessing", __FUNCTION__);
     return kMediaConduitSessionNotInited;
   }
   if(!(mPtrVoEXmedia = VoEExternalMedia::GetInterface(mVoiceEngine)))
   {
-    CSFLogError(logTag, "%s Unable to initialize VoEExternalMedia", __FUNCTION__);
+    CSFLogError(LOGTAG, "%s Unable to initialize VoEExternalMedia", __FUNCTION__);
     return kMediaConduitSessionNotInited;
   }
   if(!(mPtrVoERTP_RTCP = VoERTP_RTCP::GetInterface(mVoiceEngine)))
   {
-    CSFLogError(logTag, "%s Unable to initialize VoERTP_RTCP", __FUNCTION__);
+    CSFLogError(LOGTAG, "%s Unable to initialize VoERTP_RTCP", __FUNCTION__);
     return kMediaConduitSessionNotInited;
   }
 
   if(!(mPtrVoEVideoSync = VoEVideoSync::GetInterface(mVoiceEngine)))
   {
-    CSFLogError(logTag, "%s Unable to initialize VoEVideoSync", __FUNCTION__);
+    CSFLogError(LOGTAG, "%s Unable to initialize VoEVideoSync", __FUNCTION__);
     return kMediaConduitSessionNotInited;
   }
   if (!(mPtrRTP = webrtc::VoERTP_RTCP::GetInterface(mVoiceEngine)))
   {
-    CSFLogError(logTag, "%s Unable to get audio RTP/RTCP interface ",
+    CSFLogError(LOGTAG, "%s Unable to get audio RTP/RTCP interface ",
                 __FUNCTION__);
     return kMediaConduitSessionNotInited;
   }
 
   if( (mChannel = mPtrVoEBase->CreateChannel()) == -1)
   {
-    CSFLogError(logTag, "%s VoiceEngine Channel creation failed",__FUNCTION__);
+    CSFLogError(LOGTAG, "%s VoiceEngine Channel creation failed",__FUNCTION__);
     return kMediaConduitChannelError;
   }
   // Needed to access TelephoneEvent APIs in 57 if we're not using Call/audio_send_stream/etc
   webrtc::VoiceEngineImpl* s = static_cast<webrtc::VoiceEngineImpl*>(mVoiceEngine);
   mChannelProxy = s->GetChannelProxy(mChannel);
   MOZ_ASSERT(mChannelProxy);
 
-  CSFLogDebug(logTag, "%s Channel Created %d ",__FUNCTION__, mChannel);
+  CSFLogDebug(LOGTAG, "%s Channel Created %d ",__FUNCTION__, mChannel);
 
   if(mPtrVoENetwork->RegisterExternalTransport(mChannel, *this) == -1)
   {
-    CSFLogError(logTag, "%s VoiceEngine, External Transport Failed",__FUNCTION__);
+    CSFLogError(LOGTAG, "%s VoiceEngine, External Transport Failed",__FUNCTION__);
     return kMediaConduitTransportRegistrationFail;
   }
 
   if(mPtrVoEXmedia->SetExternalRecordingStatus(true) == -1)
   {
-    CSFLogError(logTag, "%s SetExternalRecordingStatus Failed %d",__FUNCTION__,
+    CSFLogError(LOGTAG, "%s SetExternalRecordingStatus Failed %d",__FUNCTION__,
                 mPtrVoEBase->LastError());
     return kMediaConduitExternalPlayoutError;
   }
 
   if(mPtrVoEXmedia->SetExternalPlayoutStatus(true) == -1)
   {
-    CSFLogError(logTag, "%s SetExternalPlayoutStatus Failed %d ",__FUNCTION__,
+    CSFLogError(LOGTAG, "%s SetExternalPlayoutStatus Failed %d ",__FUNCTION__,
                 mPtrVoEBase->LastError());
     return kMediaConduitExternalRecordingError;
   }
 
-  CSFLogDebug(logTag ,  "%s AudioSessionConduit Initialization Done (%p)",__FUNCTION__, this);
+  CSFLogDebug(LOGTAG ,  "%s AudioSessionConduit Initialization Done (%p)",__FUNCTION__, this);
   return kMediaConduitNoError;
 }
 
 // AudioSessionConduit Implementation
 MediaConduitErrorCode
 WebrtcAudioConduit::SetTransmitterTransport(RefPtr<TransportInterface> aTransport)
 {
-  CSFLogDebug(logTag,  "%s ", __FUNCTION__);
+  CSFLogDebug(LOGTAG,  "%s ", __FUNCTION__);
 
   ReentrantMonitorAutoEnter enter(mTransportMonitor);
   // set the transport
   mTransmitterTransport = aTransport;
   return kMediaConduitNoError;
 }
 
 MediaConduitErrorCode
 WebrtcAudioConduit::SetReceiverTransport(RefPtr<TransportInterface> aTransport)
 {
-  CSFLogDebug(logTag,  "%s ", __FUNCTION__);
+  CSFLogDebug(LOGTAG,  "%s ", __FUNCTION__);
 
   ReentrantMonitorAutoEnter enter(mTransportMonitor);
   // set the transport
   mReceiverTransport = aTransport;
   return kMediaConduitNoError;
 }
 
 MediaConduitErrorCode
 WebrtcAudioConduit::ConfigureSendMediaCodec(const AudioCodecConfig* codecConfig)
 {
-  CSFLogDebug(logTag,  "%s ", __FUNCTION__);
+  CSFLogDebug(LOGTAG,  "%s ", __FUNCTION__);
   MediaConduitErrorCode condError = kMediaConduitNoError;
   int error = 0;//webrtc engine errors
   webrtc::CodecInst cinst;
 
   {
     //validate codec param
     if((condError = ValidateCodecConfig(codecConfig, true)) != kMediaConduitNoError)
     {
@@ -436,50 +440,50 @@ WebrtcAudioConduit::ConfigureSendMediaCo
 
   condError = StopTransmitting();
   if (condError != kMediaConduitNoError) {
     return condError;
   }
 
   if(!CodecConfigToWebRTCCodec(codecConfig,cinst))
   {
-    CSFLogError(logTag,"%s CodecConfig to WebRTC Codec Failed ",__FUNCTION__);
+    CSFLogError(LOGTAG,"%s CodecConfig to WebRTC Codec Failed ",__FUNCTION__);
     return kMediaConduitMalformedArgument;
   }
 
   if(mPtrVoECodec->SetSendCodec(mChannel, cinst) == -1)
   {
     error = mPtrVoEBase->LastError();
-    CSFLogError(logTag, "%s SetSendCodec - Invalid Codec %d ",__FUNCTION__,
+    CSFLogError(LOGTAG, "%s SetSendCodec - Invalid Codec %d ",__FUNCTION__,
                                                                     error);
 
     if(error ==  VE_CANNOT_SET_SEND_CODEC || error == VE_CODEC_ERROR)
     {
-      CSFLogError(logTag, "%s Invalid Send Codec", __FUNCTION__);
+      CSFLogError(LOGTAG, "%s Invalid Send Codec", __FUNCTION__);
       return kMediaConduitInvalidSendCodec;
     }
-    CSFLogError(logTag, "%s SetSendCodec Failed %d ", __FUNCTION__,
+    CSFLogError(LOGTAG, "%s SetSendCodec Failed %d ", __FUNCTION__,
                                          mPtrVoEBase->LastError());
     return kMediaConduitUnknownError;
   }
 
   // This must be called after SetSendCodec
   if (mPtrVoECodec->SetFECStatus(mChannel, codecConfig->mFECEnabled) == -1) {
-    CSFLogError(logTag, "%s SetFECStatus Failed %d ", __FUNCTION__,
+    CSFLogError(LOGTAG, "%s SetFECStatus Failed %d ", __FUNCTION__,
                 mPtrVoEBase->LastError());
     return kMediaConduitFECStatusError;
   }
 
   mDtmfEnabled = codecConfig->mDtmfEnabled;
 
   if (codecConfig->mName == "opus" && codecConfig->mMaxPlaybackRate) {
     if (mPtrVoECodec->SetOpusMaxPlaybackRate(
           mChannel,
           codecConfig->mMaxPlaybackRate) == -1) {
-      CSFLogError(logTag, "%s SetOpusMaxPlaybackRate Failed %d ", __FUNCTION__,
+      CSFLogError(LOGTAG, "%s SetOpusMaxPlaybackRate Failed %d ", __FUNCTION__,
                   mPtrVoEBase->LastError());
       return kMediaConduitUnknownError;
     }
   }
 
   // TEMPORARY - see bug 694814 comment 2
   nsresult rv;
   nsCOMPtr<nsIPrefService> prefs = do_GetService("@mozilla.org/preferences-service;1", &rv);
@@ -510,31 +514,31 @@ WebrtcAudioConduit::ConfigureSendMediaCo
   }
   return kMediaConduitNoError;
 }
 
 MediaConduitErrorCode
 WebrtcAudioConduit::ConfigureRecvMediaCodecs(
                     const std::vector<AudioCodecConfig*>& codecConfigList)
 {
-  CSFLogDebug(logTag,  "%s ", __FUNCTION__);
+  CSFLogDebug(LOGTAG,  "%s ", __FUNCTION__);
   MediaConduitErrorCode condError = kMediaConduitNoError;
   int error = 0; //webrtc engine errors
   bool success = false;
 
   // Are we receiving already? If so, stop receiving and playout
   // since we can't apply new recv codec when the engine is playing.
   condError = StopReceiving();
   if (condError != kMediaConduitNoError) {
     return condError;
   }
 
   if(codecConfigList.empty())
   {
-    CSFLogError(logTag, "%s Zero number of codecs to configure", __FUNCTION__);
+    CSFLogError(LOGTAG, "%s Zero number of codecs to configure", __FUNCTION__);
     return kMediaConduitMalformedArgument;
   }
 
   // Try Applying the codecs in the list.
   // We succeed if at least one codec was applied and reception was
   // started successfully.
   for(auto codec : codecConfigList)
   {
@@ -542,120 +546,120 @@ WebrtcAudioConduit::ConfigureRecvMediaCo
     if((condError = ValidateCodecConfig(codec,false)) != kMediaConduitNoError)
     {
       return condError;
     }
 
     webrtc::CodecInst cinst;
     if(!CodecConfigToWebRTCCodec(codec,cinst))
     {
-      CSFLogError(logTag,"%s CodecConfig to WebRTC Codec Failed ",__FUNCTION__);
+      CSFLogError(LOGTAG,"%s CodecConfig to WebRTC Codec Failed ",__FUNCTION__);
       continue;
     }
 
     if(mPtrVoECodec->SetRecPayloadType(mChannel,cinst) == -1)
     {
       error = mPtrVoEBase->LastError();
-      CSFLogError(logTag,  "%s SetRecvCodec Failed %d ",__FUNCTION__, error);
+      CSFLogError(LOGTAG,  "%s SetRecvCodec Failed %d ",__FUNCTION__, error);
       continue;
     }
-    CSFLogDebug(logTag, "%s Successfully Set RecvCodec %s", __FUNCTION__,
+    CSFLogDebug(LOGTAG, "%s Successfully Set RecvCodec %s", __FUNCTION__,
                                         codec->mName.c_str());
 
     //copy this to local database
     if(!CopyCodecToDB(codec)) {
-        CSFLogError(logTag,"%s Unable to updated Codec Database", __FUNCTION__);
+        CSFLogError(LOGTAG,"%s Unable to updated Codec Database", __FUNCTION__);
         return kMediaConduitUnknownError;
     }
     success = true;
 
   } //end for
 
   if(!success)
   {
-    CSFLogError(logTag, "%s Setting Receive Codec Failed ", __FUNCTION__);
+    CSFLogError(LOGTAG, "%s Setting Receive Codec Failed ", __FUNCTION__);
     return kMediaConduitInvalidReceiveCodec;
   }
 
   //If we are here, atleast one codec should have been set
   condError = StartReceiving();
   if (condError != kMediaConduitNoError) {
     return condError;
   }
 
   DumpCodecDB();
   return kMediaConduitNoError;
 }
 
 MediaConduitErrorCode
 WebrtcAudioConduit::EnableAudioLevelExtension(bool enabled, uint8_t id)
 {
-  CSFLogDebug(logTag,  "%s %d %d ", __FUNCTION__, enabled, id);
+  CSFLogDebug(LOGTAG,  "%s %d %d ", __FUNCTION__, enabled, id);
 
   if (mPtrVoERTP_RTCP->SetSendAudioLevelIndicationStatus(mChannel, enabled, id) == -1)
   {
-    CSFLogError(logTag, "%s SetSendAudioLevelIndicationStatus Failed", __FUNCTION__);
+    CSFLogError(LOGTAG, "%s SetSendAudioLevelIndicationStatus Failed", __FUNCTION__);
     return kMediaConduitUnknownError;
   }
 
   return kMediaConduitNoError;
 }
 
 MediaConduitErrorCode
 WebrtcAudioConduit::EnableMIDExtension(bool enabled, uint8_t id)
 {
-  CSFLogDebug(logTag,  "%s %d %d ", __FUNCTION__, enabled, id);
+  CSFLogDebug(LOGTAG,  "%s %d %d ", __FUNCTION__, enabled, id);
 
   if (mPtrVoERTP_RTCP->SetSendMIDStatus(mChannel, enabled, id) == -1)
   {
-    CSFLogError(logTag, "%s SetSendMIDStatus Failed", __FUNCTION__);
+    CSFLogError(LOGTAG, "%s SetSendMIDStatus Failed", __FUNCTION__);
     return kMediaConduitUnknownError;
   }
 
   return kMediaConduitNoError;
 }
 
 MediaConduitErrorCode
 WebrtcAudioConduit::SendAudioFrame(const int16_t audio_data[],
                                    int32_t lengthSamples, // per channel
                                    int32_t samplingFreqHz,
                                    uint32_t channels,
                                    int32_t capture_delay)
 {
-  CSFLogDebug(logTag,  "%s ", __FUNCTION__);
+  CSFLogDebug(LOGTAG,  "%s ", __FUNCTION__);
   // Following checks need to be performed
   // 1. Non null audio buffer pointer,
   // 2. invalid sampling frequency -  less than 0 or unsupported ones
   // 3. Appropriate Sample Length for 10 ms audio-frame. This represents
   //    block size the VoiceEngine feeds into encoder for passed in audio-frame
   //    Ex: for 16000 sampling rate , valid block-length is 160
   //    Similarly for 32000 sampling rate, valid block length is 320
   //    We do the check by the verify modular operator below to be zero
 
   if(!audio_data || (lengthSamples <= 0) ||
                     (IsSamplingFreqSupported(samplingFreqHz) == false) ||
                     ((lengthSamples % (samplingFreqHz / 100) != 0)) )
   {
-    CSFLogError(logTag, "%s Invalid Parameters ",__FUNCTION__);
+    CSFLogError(LOGTAG, "%s Invalid Parameters ",__FUNCTION__);
     MOZ_ASSERT(PR_FALSE);
     return kMediaConduitMalformedArgument;
   }
 
   //validate capture time
   if(capture_delay < 0 )
   {
-    CSFLogError(logTag,"%s Invalid Capture Delay ", __FUNCTION__);
+    CSFLogError(LOGTAG,"%s Invalid Capture Delay ", __FUNCTION__);
     MOZ_ASSERT(PR_FALSE);
     return kMediaConduitMalformedArgument;
   }
 
   // if transmission is not started .. conduit cannot insert frames
   if(!mEngineTransmitting)
   {
-    CSFLogError(logTag, "%s Engine not transmitting ", __FUNCTION__);
+    CSFLogError(LOGTAG, "%s Engine not transmitting ", __FUNCTION__);
     return kMediaConduitSessionNotInited;
   }
 
   if (MOZ_LOG_TEST(GetLatencyLog(), LogLevel::Debug)) {
     struct Processing insert = { TimeStamp::Now(), 0 };
     mProcessing.AppendElement(insert);
   }
 
@@ -672,61 +676,61 @@ WebrtcAudioConduit::SendAudioFrame(const
 
 MediaConduitErrorCode
 WebrtcAudioConduit::GetAudioFrame(int16_t speechData[],
                                    int32_t samplingFreqHz,
                                    int32_t capture_delay,
                                    int& lengthSamples)
 {
 
-  CSFLogDebug(logTag,  "%s ", __FUNCTION__);
+  CSFLogDebug(LOGTAG,  "%s ", __FUNCTION__);
   unsigned int numSamples = 0;
 
   //validate params
   if(!speechData )
   {
-    CSFLogError(logTag,"%s Null Audio Buffer Pointer", __FUNCTION__);
+    CSFLogError(LOGTAG,"%s Null Audio Buffer Pointer", __FUNCTION__);
     MOZ_ASSERT(PR_FALSE);
     return kMediaConduitMalformedArgument;
   }
 
   // Validate sample length
   if((numSamples = GetNum10msSamplesForFrequency(samplingFreqHz)) == 0  )
   {
-    CSFLogError(logTag,"%s Invalid Sampling Frequency ", __FUNCTION__);
+    CSFLogError(LOGTAG,"%s Invalid Sampling Frequency ", __FUNCTION__);
     MOZ_ASSERT(PR_FALSE);
     return kMediaConduitMalformedArgument;
   }
 
   //validate capture time
   if(capture_delay < 0 )
   {
-    CSFLogError(logTag,"%s Invalid Capture Delay ", __FUNCTION__);
+    CSFLogError(LOGTAG,"%s Invalid Capture Delay ", __FUNCTION__);
     MOZ_ASSERT(PR_FALSE);
     return kMediaConduitMalformedArgument;
   }
 
   //Conduit should have reception enabled before we ask for decoded
   // samples
   if(!mEngineReceiving)
   {
-    CSFLogError(logTag, "%s Engine not Receiving ", __FUNCTION__);
+    CSFLogError(LOGTAG, "%s Engine not Receiving ", __FUNCTION__);
     return kMediaConduitSessionNotInited;
   }
 
 
   lengthSamples = 0;  //output paramter
 
   if(mPtrVoEXmedia->ExternalPlayoutGetData( speechData,
                                             samplingFreqHz,
                                             capture_delay,
                                             lengthSamples) == -1)
   {
     int error = mPtrVoEBase->LastError();
-    CSFLogError(logTag,  "%s Getting audio data Failed %d", __FUNCTION__, error);
+    CSFLogError(LOGTAG,  "%s Getting audio data Failed %d", __FUNCTION__, error);
     if(error == VE_RUNTIME_PLAY_ERROR)
     {
       return kMediaConduitPlayoutError;
     }
     return kMediaConduitUnknownError;
   }
 
   // Not #ifdef DEBUG or on a log module so we can use it for about:webrtc/etc
@@ -740,21 +744,21 @@ WebrtcAudioConduit::GetAudioFrame(int16_
                    &avsync_offset_ms)) {
       if (avsync_offset_ms < 0) {
         Telemetry::Accumulate(Telemetry::WEBRTC_AVSYNC_WHEN_VIDEO_LAGS_AUDIO_MS,
                               -avsync_offset_ms);
       } else {
         Telemetry::Accumulate(Telemetry::WEBRTC_AVSYNC_WHEN_AUDIO_LAGS_VIDEO_MS,
                               avsync_offset_ms);
       }
-      CSFLogError(logTag,
+      CSFLogError(LOGTAG,
                   "A/V sync: sync delta: %dms, audio jitter delay %dms, playout delay %dms",
                   avsync_offset_ms, jitter_buffer_delay_ms, playout_buffer_delay_ms);
     } else {
-      CSFLogError(logTag, "A/V sync: GetAVStats failed");
+      CSFLogError(LOGTAG, "A/V sync: GetAVStats failed");
     }
     mLastSyncLog = mSamples;
   }
 
   if (MOZ_LOG_TEST(GetLatencyLog(), LogLevel::Debug)) {
     if (mProcessing.Length() > 0) {
       unsigned int now;
       mPtrVoEVideoSync->GetPlayoutTimestamp(mChannel, now);
@@ -771,82 +775,82 @@ WebrtcAudioConduit::GetAudioFrame(int16_
             LogTime(AsyncLatencyLogger::AudioRecvRTP, ((uint64_t) this), delta);
             break;
           }
           mProcessing.RemoveElementAt(0);
         }
       }
     }
   }
-  CSFLogDebug(logTag,"%s GetAudioFrame:Got samples: length %d ",__FUNCTION__,
+  CSFLogDebug(LOGTAG,"%s GetAudioFrame:Got samples: length %d ",__FUNCTION__,
                                                                lengthSamples);
   return kMediaConduitNoError;
 }
 
 // Transport Layer Callbacks
 MediaConduitErrorCode
 WebrtcAudioConduit::ReceivedRTPPacket(const void *data, int len, uint32_t ssrc)
 {
-  CSFLogDebug(logTag,  "%s : channel %d", __FUNCTION__, mChannel);
+  CSFLogDebug(LOGTAG,  "%s : channel %d", __FUNCTION__, mChannel);
 
   if(mEngineReceiving)
   {
     if (MOZ_LOG_TEST(GetLatencyLog(), LogLevel::Debug)) {
       // timestamp is at 32 bits in ([1])
       struct Processing insert = { TimeStamp::Now(),
                                    ntohl(static_cast<const uint32_t *>(data)[1]) };
       mProcessing.AppendElement(insert);
     }
 
     // XXX we need to get passed the time the packet was received
     if(mPtrVoENetwork->ReceivedRTPPacket(mChannel, data, len) == -1)
     {
       int error = mPtrVoEBase->LastError();
-      CSFLogError(logTag, "%s RTP Processing Error %d", __FUNCTION__, error);
+      CSFLogError(LOGTAG, "%s RTP Processing Error %d", __FUNCTION__, error);
       if(error == VE_RTP_RTCP_MODULE_ERROR)
       {
         return kMediaConduitRTPRTCPModuleError;
       }
       return kMediaConduitUnknownError;
     }
   } else {
-    CSFLogError(logTag, "Error: %s when not receiving", __FUNCTION__);
+    CSFLogError(LOGTAG, "Error: %s when not receiving", __FUNCTION__);
     return kMediaConduitSessionNotInited;
   }
 
   return kMediaConduitNoError;
 }
 
 MediaConduitErrorCode
 WebrtcAudioConduit::ReceivedRTCPPacket(const void *data, int len)
 {
-  CSFLogDebug(logTag,  "%s : channel %d",__FUNCTION__, mChannel);
+  CSFLogDebug(LOGTAG,  "%s : channel %d",__FUNCTION__, mChannel);
 
   if(mPtrVoENetwork->ReceivedRTCPPacket(mChannel, data, len) == -1)
   {
     int error = mPtrVoEBase->LastError();
-    CSFLogError(logTag, "%s RTCP Processing Error %d", __FUNCTION__, error);
+    CSFLogError(LOGTAG, "%s RTCP Processing Error %d", __FUNCTION__, error);
     if(error == VE_RTP_RTCP_MODULE_ERROR)
     {
       return kMediaConduitRTPRTCPModuleError;
     }
     return kMediaConduitUnknownError;
   }
   return kMediaConduitNoError;
 }
 
 MediaConduitErrorCode
 WebrtcAudioConduit::StopTransmitting()
 {
   if(mEngineTransmitting)
   {
-    CSFLogDebug(logTag, "%s Engine Already Sending. Attemping to Stop ", __FUNCTION__);
+    CSFLogDebug(LOGTAG, "%s Engine Already Sending. Attemping to Stop ", __FUNCTION__);
     if(mPtrVoEBase->StopSend(mChannel) == -1)
     {
-      CSFLogError(logTag, "%s StopSend() Failed %d ", __FUNCTION__,
+      CSFLogError(LOGTAG, "%s StopSend() Failed %d ", __FUNCTION__,
                   mPtrVoEBase->LastError());
       return kMediaConduitUnknownError;
     }
     mEngineTransmitting = false;
   }
 
   return kMediaConduitNoError;
 }
@@ -854,83 +858,83 @@ WebrtcAudioConduit::StopTransmitting()
 MediaConduitErrorCode
 WebrtcAudioConduit::StartTransmitting()
 {
   if (!mEngineTransmitting) {
     //Let's Send Transport State-machine on the Engine
     if(mPtrVoEBase->StartSend(mChannel) == -1)
     {
       int error = mPtrVoEBase->LastError();
-      CSFLogError(logTag, "%s StartSend failed %d", __FUNCTION__, error);
+      CSFLogError(LOGTAG, "%s StartSend failed %d", __FUNCTION__, error);
       return kMediaConduitUnknownError;
     }
     mEngineTransmitting = true;
   }
 
   return kMediaConduitNoError;
 }
 
 MediaConduitErrorCode
 WebrtcAudioConduit::StopReceiving()
 {
   if(mEngineReceiving)
   {
-    CSFLogDebug(logTag, "%s Engine Already Receiving. Attemping to Stop ", __FUNCTION__);
+    CSFLogDebug(LOGTAG, "%s Engine Already Receiving. Attemping to Stop ", __FUNCTION__);
     // AudioEngine doesn't fail fatally on stopping reception. Ref:voe_errors.h.
     // hence we need not be strict in failing here on errors
     mPtrVoEBase->StopReceive(mChannel);
-    CSFLogDebug(logTag, "%s Attemping to Stop playout ", __FUNCTION__);
+    CSFLogDebug(LOGTAG, "%s Attemping to Stop playout ", __FUNCTION__);
     if(mPtrVoEBase->StopPlayout(mChannel) == -1)
     {
       if( mPtrVoEBase->LastError() == VE_CANNOT_STOP_PLAYOUT)
       {
-        CSFLogDebug(logTag, "%s Stop-Playout Failed %d", __FUNCTION__, mPtrVoEBase->LastError());
+        CSFLogDebug(LOGTAG, "%s Stop-Playout Failed %d", __FUNCTION__, mPtrVoEBase->LastError());
         return kMediaConduitPlayoutError;
       }
     }
     mEngineReceiving = false;
   }
 
   return kMediaConduitNoError;
 }
 
 MediaConduitErrorCode
 WebrtcAudioConduit::StartReceiving()
 {
   if (!mEngineReceiving) {
     if(mPtrVoEBase->StartReceive(mChannel) == -1)
     {
       int error = mPtrVoEBase->LastError();
-      CSFLogError(logTag ,  "%s StartReceive Failed %d ",__FUNCTION__, error);
+      CSFLogError(LOGTAG ,  "%s StartReceive Failed %d ",__FUNCTION__, error);
       if(error == VE_RECV_SOCKET_ERROR)
       {
         return kMediaConduitSocketError;
       }
       return kMediaConduitUnknownError;
     }
 
     if(mPtrVoEBase->StartPlayout(mChannel) == -1)
     {
-      CSFLogError(logTag, "%s Starting playout Failed", __FUNCTION__);
+      CSFLogError(LOGTAG, "%s Starting playout Failed", __FUNCTION__);
       return kMediaConduitPlayoutError;
     }
     mEngineReceiving = true;
   }
 
   return kMediaConduitNoError;
 }
 
 //WebRTC::RTP Callback Implementation
 // Called on AudioGUM or MSG thread
 bool
 WebrtcAudioConduit::SendRtp(const uint8_t* data,
                             size_t len,
                             const webrtc::PacketOptions& options)
 {
-  CSFLogDebug(logTag,  "%s: len %lu", __FUNCTION__, (unsigned long)len);
+  CSFLogDebug(LOGTAG,  "%s: len %lu", __FUNCTION__, (unsigned long)len);
 
   if (MOZ_LOG_TEST(GetLatencyLog(), LogLevel::Debug)) {
     if (mProcessing.Length() > 0) {
       TimeStamp started = mProcessing[0].mTimeStamp;
       mProcessing.RemoveElementAt(0);
       mProcessing.RemoveElementAt(0); // 20ms packetization!  Could automate this by watching sizes
       TimeDuration t = TimeStamp::Now() - started;
       int64_t delta = t.ToMilliseconds();
@@ -941,65 +945,65 @@ WebrtcAudioConduit::SendRtp(const uint8_
   // XXX(pkerr) - the PacketOptions are being ignored. This parameter was added along
   // with the Call API update in the webrtc.org codebase.
   // The only field in it is the packet_id, which is used when the header
   // extension for TransportSequenceNumber is being used, which we don't.
   (void)options;
   if(mTransmitterTransport &&
      (mTransmitterTransport->SendRtpPacket(data, len) == NS_OK))
   {
-    CSFLogDebug(logTag, "%s Sent RTP Packet ", __FUNCTION__);
+    CSFLogDebug(LOGTAG, "%s Sent RTP Packet ", __FUNCTION__);
     return true;
   }
-  CSFLogError(logTag, "%s RTP Packet Send Failed ", __FUNCTION__);
+  CSFLogError(LOGTAG, "%s RTP Packet Send Failed ", __FUNCTION__);
   return false;
 }
 
 // Called on WebRTC Process thread and perhaps others
 bool
 WebrtcAudioConduit::SendRtcp(const uint8_t* data, size_t len)
 {
-  CSFLogDebug(logTag, "%s : len %lu, first rtcp = %u ",
+  CSFLogDebug(LOGTAG, "%s : len %lu, first rtcp = %u ",
               __FUNCTION__,
               (unsigned long) len,
               static_cast<unsigned>(data[1]));
 
   // We come here if we have only one pipeline/conduit setup,
   // such as for unidirectional streams.
   // We also end up here if we are receiving
   ReentrantMonitorAutoEnter enter(mTransportMonitor);
   if(mReceiverTransport &&
      mReceiverTransport->SendRtcpPacket(data, len) == NS_OK)
   {
     // Might be a sender report, might be a receiver report, we don't know.
-    CSFLogDebug(logTag, "%s Sent RTCP Packet ", __FUNCTION__);
+    CSFLogDebug(LOGTAG, "%s Sent RTCP Packet ", __FUNCTION__);
     return true;
   }
   if (mTransmitterTransport &&
       (mTransmitterTransport->SendRtcpPacket(data, len) == NS_OK)) {
-    CSFLogDebug(logTag, "%s Sent RTCP Packet (sender report) ", __FUNCTION__);
+    CSFLogDebug(LOGTAG, "%s Sent RTCP Packet (sender report) ", __FUNCTION__);
     return true;
   }
-  CSFLogError(logTag, "%s RTCP Packet Send Failed ", __FUNCTION__);
+  CSFLogError(LOGTAG, "%s RTCP Packet Send Failed ", __FUNCTION__);
   return false;
 }
 
 /**
  * Converts between CodecConfig to WebRTC Codec Structure.
  */
 
 bool
 WebrtcAudioConduit::CodecConfigToWebRTCCodec(const AudioCodecConfig* codecInfo,
                                               webrtc::CodecInst& cinst)
 {
   const unsigned int plNameLength = codecInfo->mName.length();
   memset(&cinst, 0, sizeof(webrtc::CodecInst));
   if(sizeof(cinst.plname) < plNameLength+1)
   {
-    CSFLogError(logTag, "%s Payload name buffer capacity mismatch ",
+    CSFLogError(LOGTAG, "%s Payload name buffer capacity mismatch ",
                                                       __FUNCTION__);
     return false;
   }
   memcpy(cinst.plname, codecInfo->mName.c_str(), plNameLength);
   cinst.plname[plNameLength]='\0';
   cinst.pltype   =  codecInfo->mType;
   cinst.rate     =  codecInfo->mRate;
   cinst.pacsize  =  codecInfo->mPacSize;
@@ -1103,57 +1107,57 @@ WebrtcAudioConduit::CheckCodecForMatch(c
 MediaConduitErrorCode
 WebrtcAudioConduit::ValidateCodecConfig(const AudioCodecConfig* codecInfo,
                                         bool send)
 {
   bool codecAppliedAlready = false;
 
   if(!codecInfo)
   {
-    CSFLogError(logTag, "%s Null CodecConfig ", __FUNCTION__);
+    CSFLogError(LOGTAG, "%s Null CodecConfig ", __FUNCTION__);
     return kMediaConduitMalformedArgument;
   }
 
   if((codecInfo->mName.empty()) ||
      (codecInfo->mName.length() >= CODEC_PLNAME_SIZE))
   {
-    CSFLogError(logTag, "%s Invalid Payload Name Length ", __FUNCTION__);
+    CSFLogError(LOGTAG, "%s Invalid Payload Name Length ", __FUNCTION__);
     return kMediaConduitMalformedArgument;
   }
 
   //Only mono or stereo channels supported
   if( (codecInfo->mChannels != 1) && (codecInfo->mChannels != 2))
   {
-    CSFLogError(logTag, "%s Channel Unsupported ", __FUNCTION__);
+    CSFLogError(LOGTAG, "%s Channel Unsupported ", __FUNCTION__);
     return kMediaConduitMalformedArgument;
   }
 
   //check if we have the same codec already applied
   if(send)
   {
     MutexAutoLock lock(mCodecMutex);
 
     codecAppliedAlready = CheckCodecsForMatch(mCurSendCodecConfig,codecInfo);
   } else {
     codecAppliedAlready = CheckCodecForMatch(codecInfo);
   }
 
   if(codecAppliedAlready)
   {
-    CSFLogDebug(logTag, "%s Codec %s Already Applied  ", __FUNCTION__, codecInfo->mName.c_str());
+    CSFLogDebug(LOGTAG, "%s Codec %s Already Applied  ", __FUNCTION__, codecInfo->mName.c_str());
   }
   return kMediaConduitNoError;
 }
 
 void
 WebrtcAudioConduit::DumpCodecDB() const
  {
     for(auto& codec : mRecvCodecList)
     {
-      CSFLogDebug(logTag,"Payload Name: %s", codec->mName.c_str());
-      CSFLogDebug(logTag,"Payload Type: %d", codec->mType);
-      CSFLogDebug(logTag,"Payload Frequency: %d", codec->mFreq);
-      CSFLogDebug(logTag,"Payload PacketSize: %d", codec->mPacSize);
-      CSFLogDebug(logTag,"Payload Channels: %d", codec->mChannels);
-      CSFLogDebug(logTag,"Payload Sampling Rate: %d", codec->mRate);
+      CSFLogDebug(LOGTAG,"Payload Name: %s", codec->mName.c_str());
+      CSFLogDebug(LOGTAG,"Payload Type: %d", codec->mType);
+      CSFLogDebug(LOGTAG,"Payload Frequency: %d", codec->mFreq);
+      CSFLogDebug(LOGTAG,"Payload PacketSize: %d", codec->mPacSize);
+      CSFLogDebug(LOGTAG,"Payload Channels: %d", codec->mChannels);
+      CSFLogDebug(LOGTAG,"Payload Sampling Rate: %d", codec->mRate);
     }
  }
 }// end namespace
--- a/media/webrtc/signaling/src/media-conduit/MediaCodecVideoCodec.cpp
+++ b/media/webrtc/signaling/src/media-conduit/MediaCodecVideoCodec.cpp
@@ -6,31 +6,35 @@
 #include "nspr.h"
 
 #include "WebrtcMediaCodecVP8VideoCodec.h"
 #include "MediaCodecVideoCodec.h"
 #include "MediaPrefs.h"
 
 namespace mozilla {
 
-static const char* logTag ="MediaCodecVideoCodec";
+static const char* mcvcLogTag ="MediaCodecVideoCodec";
+#ifdef LOGTAG
+#undef LOGTAG
+#endif
+#define LOGTAG mcvcLogTag
 
 WebrtcVideoEncoder* MediaCodecVideoCodec::CreateEncoder(CodecType aCodecType) {
-  CSFLogDebug(logTag,  "%s ", __FUNCTION__);
+  CSFLogDebug(LOGTAG,  "%s ", __FUNCTION__);
   if (aCodecType == CODEC_VP8) {
     if (MediaPrefs::RemoteMediaCodecVP8EncoderEnabled()) {
       return new WebrtcMediaCodecVP8VideoRemoteEncoder();
     } else {
       return new WebrtcMediaCodecVP8VideoEncoder();
     }
   }
   return nullptr;
 }
 
 WebrtcVideoDecoder* MediaCodecVideoCodec::CreateDecoder(CodecType aCodecType) {
-  CSFLogDebug(logTag,  "%s ", __FUNCTION__);
+  CSFLogDebug(LOGTAG,  "%s ", __FUNCTION__);
   if (aCodecType == CODEC_VP8) {
     return new WebrtcMediaCodecVP8VideoDecoder();
   }
   return nullptr;
 }
 
 }
--- a/media/webrtc/signaling/src/media-conduit/VideoConduit.cpp
+++ b/media/webrtc/signaling/src/media-conduit/VideoConduit.cpp
@@ -65,17 +65,21 @@
 #include <math.h>
 #include <cinttypes>
 
 #define DEFAULT_VIDEO_MAX_FRAMERATE 30
 #define INVALID_RTP_PAYLOAD 255 // valid payload types are 0 to 127
 
 namespace mozilla {
 
-static const char* logTag = "WebrtcVideoSessionConduit";
+static const char* vcLogTag = "WebrtcVideoSessionConduit";
+#ifdef LOGTAG
+#undef LOGTAG
+#endif
+#define LOGTAG vcLogTag
 
 static const int kNullPayloadType = -1;
 static const char* kUlpFecPayloadName = "ulpfec";
 static const char* kRedPayloadName = "red";
 
 // Convert (SI) kilobits/sec to (SI) bits/sec
 #define KBPS(kbps) kbps * 1000
 const uint32_t WebrtcVideoConduit::kDefaultMinBitrate_bps =  KBPS(200);
@@ -166,24 +170,24 @@ void
 WebrtcVideoConduit::SendStreamStatistics::Update(
   const webrtc::VideoSendStream::Stats& aStats)
 {
   StreamStatistics::Update(aStats.encode_frame_rate, aStats.media_bitrate_bps);
   if (!aStats.substreams.empty()) {
     const webrtc::FrameCounts& fc =
       aStats.substreams.begin()->second.frame_counts;
     mFramesEncoded = fc.key_frames + fc.delta_frames;
-    CSFLogVerbose(logTag,
+    CSFLogVerbose(LOGTAG,
                   "%s: framerate: %u, bitrate: %u, dropped frames delta: %u",
                   __FUNCTION__, aStats.encode_frame_rate,
                   aStats.media_bitrate_bps,
                   mFramesDeliveredToEncoder - mFramesEncoded - mDroppedFrames);
     mDroppedFrames = mFramesDeliveredToEncoder - mFramesEncoded;
   } else {
-    CSFLogVerbose(logTag, "%s stats.substreams is empty", __FUNCTION__);
+    CSFLogVerbose(LOGTAG, "%s stats.substreams is empty", __FUNCTION__);
   }
 }
 
 void
 WebrtcVideoConduit::ReceiveStreamStatistics::DiscardedPackets(
   uint32_t& aOutDiscPackets) const
 {
   aOutDiscPackets = mDiscardedPackets;
@@ -195,43 +199,43 @@ WebrtcVideoConduit::ReceiveStreamStatist
 {
   aFramesDecoded = mFramesDecoded;
 }
 
 void
 WebrtcVideoConduit::ReceiveStreamStatistics::Update(
   const webrtc::VideoReceiveStream::Stats& aStats)
 {
-  CSFLogVerbose(logTag, "%s ", __FUNCTION__);
+  CSFLogVerbose(LOGTAG, "%s ", __FUNCTION__);
   StreamStatistics::Update(aStats.decode_frame_rate, aStats.total_bitrate_bps);
   mDiscardedPackets = aStats.discarded_packets;
   mFramesDecoded = aStats.frame_counts.key_frames
                    + aStats.frame_counts.delta_frames;
 }
 
 /**
  * Factory Method for VideoConduit
  */
 RefPtr<VideoSessionConduit>
 VideoSessionConduit::Create(RefPtr<WebRtcCallWrapper> aCall)
 {
   NS_ASSERTION(NS_IsMainThread(), "Only call on main thread");
   NS_ASSERTION(aCall, "missing required parameter: aCall");
-  CSFLogVerbose(logTag, "%s", __FUNCTION__);
+  CSFLogVerbose(LOGTAG, "%s", __FUNCTION__);
 
   if (!aCall) {
     return nullptr;
   }
 
   nsAutoPtr<WebrtcVideoConduit> obj(new WebrtcVideoConduit(aCall));
   if(obj->Init() != kMediaConduitNoError) {
-    CSFLogError(logTag, "%s VideoConduit Init Failed ", __FUNCTION__);
+    CSFLogError(LOGTAG, "%s VideoConduit Init Failed ", __FUNCTION__);
     return nullptr;
   }
-  CSFLogVerbose(logTag, "%s Successfully created VideoConduit ", __FUNCTION__);
+  CSFLogVerbose(LOGTAG, "%s Successfully created VideoConduit ", __FUNCTION__);
   return obj.forget();
 }
 
 WebrtcVideoConduit::WebrtcVideoConduit(RefPtr<WebRtcCallWrapper> aCall)
   : mTransportMonitor("WebrtcVideoConduit")
   , mRenderer(nullptr)
   , mVideoAdapter(1)
   , mVideoBroadcaster()
@@ -271,17 +275,17 @@ WebrtcVideoConduit::WebrtcVideoConduit(R
   , mSendCodecPlugin(nullptr)
   , mRecvCodecPlugin(nullptr)
   , mVideoStatsTimer(do_CreateInstance(NS_TIMER_CONTRACTID))
 {
   mRecvStreamConfig.renderer = this;
 
   // Video Stats Callback
   nsTimerCallbackFunc callback = [](nsITimer* aTimer, void* aClosure) {
-    CSFLogDebug(logTag, "StreamStats polling scheduled for VideoConduit: %p", aClosure);
+    CSFLogDebug(LOGTAG, "StreamStats polling scheduled for VideoConduit: %p", aClosure);
     auto self = static_cast<WebrtcVideoConduit*>(aClosure);
     MutexAutoLock lock(self->mCodecMutex);
     if (self->mEngineTransmitting && self->mSendStream) {
       const auto& stats = self->mSendStream->GetStats();
       self->mSendStreamStats.Update(stats);
       if (!stats.substreams.empty()) {
           self->mSendPacketCounts =
             stats.substreams.begin()->second.rtcp_packet_type_counts;
@@ -295,22 +299,22 @@ WebrtcVideoConduit::WebrtcVideoConduit(R
   };
   mVideoStatsTimer->InitWithNamedFuncCallback(
     callback, this, 1000, nsITimer::TYPE_REPEATING_PRECISE_CAN_SKIP,
     "WebrtcVideoConduit::WebrtcVideoConduit");
 }
 
 WebrtcVideoConduit::~WebrtcVideoConduit()
 {
-  CSFLogDebug(logTag, "%s ", __FUNCTION__);
+  CSFLogDebug(LOGTAG, "%s ", __FUNCTION__);
   NS_ASSERTION(NS_IsMainThread(), "Only call on main thread");
   if (mVideoStatsTimer) {
-    CSFLogDebug(logTag, "canceling StreamStats for VideoConduit: %p", this);
+    CSFLogDebug(LOGTAG, "canceling StreamStats for VideoConduit: %p", this);
     MutexAutoLock lock(mCodecMutex);
-    CSFLogDebug(logTag, "StreamStats cancelled for VideoConduit: %p", this);
+    CSFLogDebug(LOGTAG, "StreamStats cancelled for VideoConduit: %p", this);
     mVideoStatsTimer->Cancel();
   }
 
   // Release AudioConduit first by dropping reference on MainThread, where it expects to be
   SyncTo(nullptr);
   Destroy();
 }
 
@@ -374,17 +378,17 @@ bool WebrtcVideoConduit::SetLocalMID(con
 {
   mSendStreamConfig.rtp.mid = mid;
   return true;
 }
 
 MediaConduitErrorCode
 WebrtcVideoConduit::ConfigureCodecMode(webrtc::VideoCodecMode mode)
 {
-  CSFLogVerbose(logTag, "%s ", __FUNCTION__);
+  CSFLogVerbose(LOGTAG, "%s ", __FUNCTION__);
   if (mode == webrtc::VideoCodecMode::kRealtimeVideo ||
       mode == webrtc::VideoCodecMode::kScreensharing) {
     mCodecMode = mode;
     return kMediaConduitNoError;
   }
 
   return kMediaConduitMalformedArgument;
 }
@@ -472,28 +476,28 @@ WebrtcVideoConduit::CreateRecvStream()
   std::unique_ptr<webrtc::VideoDecoder> decoder;
   webrtc::VideoCodecType decoder_type;
 
   mRecvStreamConfig.decoders.clear();
   for (auto& config : mRecvCodecList) {
     decoder_type = SupportedCodecType(webrtc::PayloadNameToCodecType(config->mName)
                                       .value_or(webrtc::VideoCodecType::kVideoCodecUnknown));
     if (decoder_type == webrtc::VideoCodecType::kVideoCodecUnknown) {
-      CSFLogError(logTag, "%s Unknown decoder type: %s", __FUNCTION__,
+      CSFLogError(LOGTAG, "%s Unknown decoder type: %s", __FUNCTION__,
                   config->mName.c_str());
       continue;
     }
 
     decoder.reset(CreateDecoder(decoder_type));
 
     if (!decoder) {
       // This really should never happen unless something went wrong
       // in the negotiation code
       NS_ASSERTION(decoder, "Failed to create video decoder");
-      CSFLogError(logTag, "Failed to create decoder of type %s (%d)",
+      CSFLogError(LOGTAG, "Failed to create decoder of type %s (%d)",
                   config->mName.c_str(), decoder_type);
       // don't stop
       continue;
     }
 
     decoder_desc.decoder = decoder.get();
     mDecoders.push_back(std::move(decoder));
     decoder_desc.payload_name = config->mName;
@@ -503,17 +507,17 @@ WebrtcVideoConduit::CreateRecvStream()
     mRecvStreamConfig.decoders.push_back(decoder_desc);
   }
 
   mRecvStream = mCall->Call()->CreateVideoReceiveStream(mRecvStreamConfig.Copy());
   if (!mRecvStream) {
     mDecoders.clear();
     return kMediaConduitUnknownError;
   }
-  CSFLogDebug(logTag, "Created VideoReceiveStream %p for SSRC %u (0x%x)",
+  CSFLogDebug(LOGTAG, "Created VideoReceiveStream %p for SSRC %u (0x%x)",
               mRecvStream, mRecvStreamConfig.rtp.remote_ssrc, mRecvStreamConfig.rtp.remote_ssrc);
 
   return kMediaConduitNoError;
 }
 
 static rtc::scoped_refptr<webrtc::VideoEncoderConfig::EncoderSpecificSettings>
 ConfigureVideoEncoderSettings(const VideoCodecConfig* aConfig,
                               const WebrtcVideoConduit* aConduit)
@@ -590,22 +594,22 @@ WebrtcVideoConduit::VideoStreamFactory::
 #if 0
   // XXX What we'd like to do for each simulcast stream...
   if (simulcastEncoding.constraints.scaleDownBy > 1.0) {
     uint32_t new_width = width / simulcastEncoding.constraints.scaleDownBy;
     uint32_t new_height = height / simulcastEncoding.constraints.scaleDownBy;
 
     if (new_width != width || new_height != height) {
       if (streamCount == 1) {
-        CSFLogVerbose(logTag, "%s: ConstrainPreservingAspectRatio", __FUNCTION__);
+        CSFLogVerbose(LOGTAG, "%s: ConstrainPreservingAspectRatio", __FUNCTION__);
         // Use less strict scaling in unicast. That way 320x240 / 3 = 106x79.
         ConstrainPreservingAspectRatio(new_width, new_height,
                                        &width, &height);
       } else {
-        CSFLogVerbose(logTag, "%s: ConstrainPreservingAspectRatioExact", __FUNCTION__);
+        CSFLogVerbose(LOGTAG, "%s: ConstrainPreservingAspectRatioExact", __FUNCTION__);
         // webrtc.org supposedly won't tolerate simulcast unless every stream
         // is exactly the same aspect ratio. 320x240 / 3 = 80x60.
         ConstrainPreservingAspectRatioExact(new_width * new_height,
                                             &width, &height);
       }
     }
   }
 #endif
@@ -669,17 +673,17 @@ WebrtcVideoConduit::VideoStreamFactory::
     }
 
     video_stream.max_qp = kQpMax;
     video_stream.SetRid(simulcastEncoding.rid);
 
     if (mConduit->mCurSendCodecConfig->mName == "H264") {
       if (mConduit->mCurSendCodecConfig->mEncodingConstraints.maxMbps > 0) {
         // Not supported yet!
-        CSFLogError(logTag, "%s H.264 max_mbps not supported yet", __FUNCTION__);
+        CSFLogError(LOGTAG, "%s H.264 max_mbps not supported yet", __FUNCTION__);
       }
     }
     streams.push_back(video_stream);
   }
   return streams;
 }
 
 /**
@@ -691,29 +695,29 @@ WebrtcVideoConduit::VideoStreamFactory::
  * renegotiation/reconfiguration, this now needs a lock!  Alternatively
  * changes could be queued until the next frame is delivered using an
  * Atomic pointer and swaps.
  */
 
 MediaConduitErrorCode
 WebrtcVideoConduit::ConfigureSendMediaCodec(const VideoCodecConfig* codecConfig)
 {
-  CSFLogDebug(logTag, "%s for %s", __FUNCTION__,
+  CSFLogDebug(LOGTAG, "%s for %s", __FUNCTION__,
     codecConfig ? codecConfig->mName.c_str() : "<null>");
 
   MediaConduitErrorCode condError = kMediaConduitNoError;
 
   // validate basic params
   if ((condError = ValidateCodecConfig(codecConfig)) != kMediaConduitNoError) {
     return condError;
   }
 
   size_t streamCount = std::min(codecConfig->mSimulcastEncodings.size(),
                                 (size_t)webrtc::kMaxSimulcastStreams);
-  CSFLogDebug(logTag, "%s for VideoConduit:%p stream count:%d", __FUNCTION__,
+  CSFLogDebug(LOGTAG, "%s for VideoConduit:%p stream count:%d", __FUNCTION__,
               this, static_cast<int>(streamCount));
 
   mSendingFramerate = 0;
   mEncoderConfig.ClearStreams();
   mSendStreamConfig.rtp.rids.clear();
 
   int max_framerate;
   if (codecConfig->mEncodingConstraints.maxFps > 0) {
@@ -851,17 +855,17 @@ WebrtcVideoConduit::ConfigureSendMediaCo
   }
 
   return condError;
 }
 
 bool
 WebrtcVideoConduit::SetRemoteSSRC(unsigned int ssrc)
 {
-  CSFLogDebug(logTag, "%s: SSRC %u (0x%x)", __FUNCTION__, ssrc, ssrc);
+  CSFLogDebug(LOGTAG, "%s: SSRC %u (0x%x)", __FUNCTION__, ssrc, ssrc);
   mRecvStreamConfig.rtp.remote_ssrc = ssrc;
 
   unsigned int current_ssrc;
   if (!GetRemoteSSRC(&current_ssrc)) {
     return false;
   }
 
   if (current_ssrc == ssrc) {
@@ -882,17 +886,17 @@ WebrtcVideoConduit::SetRemoteSSRC(unsign
     // On the next StartReceiving() or ConfigureRecvMediaCodec, force
     // building a new RecvStream to switch SSRCs.
     DeleteRecvStream();
     if (!wasReceiving) {
       return true;
     }
     MediaConduitErrorCode rval = CreateRecvStream();
     if (rval != kMediaConduitNoError) {
-      CSFLogError(logTag, "%s Start Receive Error %d ", __FUNCTION__, rval);
+      CSFLogError(LOGTAG, "%s Start Receive Error %d ", __FUNCTION__, rval);
       return false;
     }
   }
   return (StartReceiving() == kMediaConduitNoError);
 }
 
 bool
 WebrtcVideoConduit::GetRemoteSSRC(unsigned int* ssrc)
@@ -983,17 +987,17 @@ WebrtcVideoConduit::GetAVStats(int32_t* 
 {
   return false;
 }
 
 bool
 WebrtcVideoConduit::GetRTPStats(unsigned int* jitterMs,
                                 unsigned int* cumulativeLost)
 {
-  CSFLogVerbose(logTag, "%s for VideoConduit:%p", __FUNCTION__, this);
+  CSFLogVerbose(LOGTAG, "%s for VideoConduit:%p", __FUNCTION__, this);
   {
     MutexAutoLock lock(mCodecMutex);
     if (!mRecvStream) {
       return false;
     }
 
     const webrtc::VideoReceiveStream::Stats& stats = mRecvStream->GetStats();
     *jitterMs =
@@ -1006,44 +1010,44 @@ WebrtcVideoConduit::GetRTPStats(unsigned
 bool WebrtcVideoConduit::GetRTCPReceiverReport(DOMHighResTimeStamp* timestamp,
                                                uint32_t* jitterMs,
                                                uint32_t* packetsReceived,
                                                uint64_t* bytesReceived,
                                                uint32_t* cumulativeLost,
                                                int32_t* rttMs)
 {
   {
-    CSFLogVerbose(logTag, "%s for VideoConduit:%p", __FUNCTION__, this);
+    CSFLogVerbose(LOGTAG, "%s for VideoConduit:%p", __FUNCTION__, this);
     MutexAutoLock lock(mCodecMutex);
     if (!mSendStream) {
       return false;
     }
     const webrtc::VideoSendStream::Stats& sendStats = mSendStream->GetStats();
     if (sendStats.substreams.empty()
         || mSendStreamConfig.rtp.ssrcs.empty()) {
       return false;
     }
     uint32_t ssrc = mSendStreamConfig.rtp.ssrcs.front();
     auto ind = sendStats.substreams.find(ssrc);
     if (ind == sendStats.substreams.end()) {
-      CSFLogError(logTag,
+      CSFLogError(LOGTAG,
         "%s for VideoConduit:%p ssrc not found in SendStream stats.",
         __FUNCTION__, this);
       return false;
     }
     *jitterMs = ind->second.rtcp_stats.jitter
         / (webrtc::kVideoPayloadTypeFrequency / 1000);
     *cumulativeLost = ind->second.rtcp_stats.cumulative_lost;
     *bytesReceived = ind->second.rtp_stats.MediaPayloadBytes();
     *packetsReceived = ind->second.rtp_stats.transmitted.packets;
     auto stats = mCall->Call()->GetStats();
     int64_t rtt = stats.rtt_ms;
 #ifdef DEBUG
     if (rtt > INT32_MAX) {
-      CSFLogError(logTag,
+      CSFLogError(LOGTAG,
         "%s for VideoConduit:%p RTT is larger than the"
         " maximum size of an RTCP RTT.", __FUNCTION__, this);
     }
 #endif
     if (rtt > 0) {
       *rttMs = rtt;
     } else {
       *rttMs = 0;
@@ -1055,17 +1059,17 @@ bool WebrtcVideoConduit::GetRTCPReceiver
   return true;
 }
 
 bool
 WebrtcVideoConduit::GetRTCPSenderReport(DOMHighResTimeStamp* timestamp,
                                         unsigned int* packetsSent,
                                         uint64_t* bytesSent)
 {
-  CSFLogVerbose(logTag, "%s for VideoConduit:%p", __FUNCTION__, this);
+  CSFLogVerbose(LOGTAG, "%s for VideoConduit:%p", __FUNCTION__, this);
   webrtc::RTCPSenderInfo senderInfo;
   {
     MutexAutoLock lock(mCodecMutex);
     if (!mRecvStream || !mRecvStream->GetRemoteRTCPSenderInfo(&senderInfo)) {
       return false;
     }
   }
   *timestamp = webrtc::Clock::GetRealTimeClock()->TimeInMilliseconds();
@@ -1150,39 +1154,39 @@ WebrtcVideoConduit::InitMain()
         "media.peerconnection.video.lock_scaling", &mLockScaling)));
     }
   }
 #ifdef MOZ_WIDGET_ANDROID
   // get the JVM
   JavaVM *jvm = jsjni_GetVM();
 
   if (mozilla::camera::VideoEngine::SetAndroidObjects(jvm) != 0) {
-    CSFLogError(logTag,  "%s: could not set Android objects", __FUNCTION__);
+    CSFLogError(LOGTAG,  "%s: could not set Android objects", __FUNCTION__);
     return kMediaConduitSessionNotInited;
   }
 #endif  //MOZ_WIDGET_ANDROID
   return kMediaConduitNoError;
 }
 
 /**
  * Performs initialization of the MANDATORY components of the Video Engine
  */
 MediaConduitErrorCode
 WebrtcVideoConduit::Init()
 {
-  CSFLogDebug(logTag, "%s this=%p", __FUNCTION__, this);
+  CSFLogDebug(LOGTAG, "%s this=%p", __FUNCTION__, this);
   MediaConduitErrorCode result;
   // Run code that must run on MainThread first
   MOZ_ASSERT(NS_IsMainThread());
   result = InitMain();
   if (result != kMediaConduitNoError) {
     return result;
   }
 
-  CSFLogError(logTag, "%s Initialization Done", __FUNCTION__);
+  CSFLogError(LOGTAG, "%s Initialization Done", __FUNCTION__);
   return kMediaConduitNoError;
 }
 
 void
 WebrtcVideoConduit::Destroy()
 {
   // We can't delete the VideoEngine until all these are released!
   // And we can't use a Scoped ptr, since the order is arbitrary
@@ -1190,22 +1194,22 @@ WebrtcVideoConduit::Destroy()
   MutexAutoLock lock(mCodecMutex);
   DeleteSendStream();
   DeleteRecvStream();
 }
 
 void
 WebrtcVideoConduit::SyncTo(WebrtcAudioConduit* aConduit)
 {
-  CSFLogDebug(logTag, "%s Synced to %p", __FUNCTION__, aConduit);
+  CSFLogDebug(LOGTAG, "%s Synced to %p", __FUNCTION__, aConduit);
   {
     MutexAutoLock lock(mCodecMutex);
 
     if (!mRecvStream) {
-      CSFLogError(logTag, "SyncTo called with no receive stream");
+      CSFLogError(LOGTAG, "SyncTo called with no receive stream");
       return;
     }
 
     if (aConduit) {
       mRecvStream->SetSyncChannel(aConduit->GetVoiceEngine(),
                                   aConduit->GetChannel());
     } else if (mSyncedTo) {
       mRecvStream->SetSyncChannel(mSyncedTo->GetVoiceEngine(), -1);
@@ -1213,21 +1217,21 @@ WebrtcVideoConduit::SyncTo(WebrtcAudioCo
   }
 
   mSyncedTo = aConduit;
 }
 
 MediaConduitErrorCode
 WebrtcVideoConduit::AttachRenderer(RefPtr<mozilla::VideoRenderer> aVideoRenderer)
 {
-  CSFLogDebug(logTag, "%s", __FUNCTION__);
+  CSFLogDebug(LOGTAG, "%s", __FUNCTION__);
 
   // null renderer
   if (!aVideoRenderer) {
-    CSFLogError(logTag, "%s NULL Renderer", __FUNCTION__);
+    CSFLogError(LOGTAG, "%s NULL Renderer", __FUNCTION__);
     MOZ_ASSERT(false);
     return kMediaConduitInvalidRenderer;
   }
 
   // This function is called only from main, so we only need to protect against
   // modifying mRenderer while any webrtc.org code is trying to use it.
   {
     ReentrantMonitorAutoEnter enter(mTransportMonitor);
@@ -1251,45 +1255,45 @@ WebrtcVideoConduit::DetachRenderer()
     }
   }
 }
 
 MediaConduitErrorCode
 WebrtcVideoConduit::SetTransmitterTransport(
   RefPtr<TransportInterface> aTransport)
 {
-  CSFLogDebug(logTag, "%s ", __FUNCTION__);
+  CSFLogDebug(LOGTAG, "%s ", __FUNCTION__);
 
   ReentrantMonitorAutoEnter enter(mTransportMonitor);
   // set the transport
   mTransmitterTransport = aTransport;
   return kMediaConduitNoError;
 }
 
 MediaConduitErrorCode
 WebrtcVideoConduit::SetReceiverTransport(RefPtr<TransportInterface> aTransport)
 {
-  CSFLogDebug(logTag, "%s ", __FUNCTION__);
+  CSFLogDebug(LOGTAG, "%s ", __FUNCTION__);
 
   ReentrantMonitorAutoEnter enter(mTransportMonitor);
   // set the transport
   mReceiverTransport = aTransport;
   return kMediaConduitNoError;
 }
 
 MediaConduitErrorCode
 WebrtcVideoConduit::ConfigureRecvMediaCodecs(
   const std::vector<VideoCodecConfig* >& codecConfigList)
 {
-  CSFLogDebug(logTag, "%s ", __FUNCTION__);
+  CSFLogDebug(LOGTAG, "%s ", __FUNCTION__);
   MediaConduitErrorCode condError = kMediaConduitNoError;
   std::string payloadName;
 
   if (codecConfigList.empty()) {
-    CSFLogError(logTag, "%s Zero number of codecs to configure", __FUNCTION__);
+    CSFLogError(LOGTAG, "%s Zero number of codecs to configure", __FUNCTION__);
     return kMediaConduitMalformedArgument;
   }
 
   webrtc::KeyFrameRequestMethod kf_request_method = webrtc::kKeyFrameReqPliRtcp;
   bool kf_request_enabled = false;
   bool use_nack_basic = false;
   bool use_tmmbr = false;
   bool use_remb = false;
@@ -1301,17 +1305,17 @@ WebrtcVideoConduit::ConfigureRecvMediaCo
 
   // Try Applying the codecs in the list
   // we treat as success if at least one codec was applied and reception was
   // started successfully.
   std::set<unsigned int> codec_types_seen;
   for (const auto& codec_config : codecConfigList) {
     if ((condError = ValidateCodecConfig(codec_config))
         != kMediaConduitNoError) {
-      CSFLogError(logTag, "%s Invalid config for %s decoder: %i", __FUNCTION__,
+      CSFLogError(LOGTAG, "%s Invalid config for %s decoder: %i", __FUNCTION__,
                   codec_config ? codec_config->mName.c_str() : "<null>",
                   condError);
       continue;
     }
     if (codec_config->mName == "H264") {
       // TODO(bug 1200768): We can only handle configuring one recv H264 codec
       if (configuredH264) {
         continue;
@@ -1348,17 +1352,17 @@ WebrtcVideoConduit::ConfigureRecvMediaCo
     use_tmmbr |= codec_config->RtcpFbCcmIsSet("tmmbr");
     use_remb |= codec_config->RtcpFbRembIsSet();
     use_fec |= codec_config->RtcpFbFECIsSet();
 
     recv_codecs.AppendElement(new VideoCodecConfig(*codec_config));
   }
 
   if (!recv_codecs.Length()) {
-    CSFLogError(logTag, "%s Found no valid receive codecs", __FUNCTION__);
+    CSFLogError(LOGTAG, "%s Found no valid receive codecs", __FUNCTION__);
     return kMediaConduitMalformedArgument;
   }
 
   // Now decide if we need to recreate the receive stream, or can keep it
   if (!mRecvStream ||
       CodecsDifferent(recv_codecs, mRecvCodecList) ||
       mRecvStreamConfig.rtp.nack.rtp_history_ms != (use_nack_basic ? 1000 : 0) ||
       mRecvStreamConfig.rtp.remb != use_remb ||
@@ -1421,33 +1425,33 @@ WebrtcVideoConduit::ConfigureRecvMediaCo
       SECStatus rv = PK11_GenerateRandom(reinterpret_cast<unsigned char*>(&ssrc), sizeof(ssrc));
       if (rv != SECSuccess) {
         return kMediaConduitUnknownError;
       }
     }
     // webrtc.org code has fits if you select an SSRC of 0
 
     mRecvStreamConfig.rtp.local_ssrc = ssrc;
-    CSFLogDebug(logTag, "%s (%p): Local SSRC 0x%08x (of %u), remote SSRC 0x%08x",
+    CSFLogDebug(LOGTAG, "%s (%p): Local SSRC 0x%08x (of %u), remote SSRC 0x%08x",
                 __FUNCTION__, (void*) this, ssrc,
                 (uint32_t) mSendStreamConfig.rtp.ssrcs.size(),
                 mRecvStreamConfig.rtp.remote_ssrc);
 
     // XXX Copy over those that are the same and don't rebuild them
     mRecvCodecList.SwapElements(recv_codecs);
     recv_codecs.Clear();
     mRecvStreamConfig.rtp.rtx.clear();
 
     {
       MutexAutoLock lock(mCodecMutex);
       DeleteRecvStream();
       // Rebuilds mRecvStream from mRecvStreamConfig
       MediaConduitErrorCode rval = CreateRecvStream();
       if (rval != kMediaConduitNoError) {
-        CSFLogError(logTag, "%s Start Receive Error %d ", __FUNCTION__, rval);
+        CSFLogError(LOGTAG, "%s Start Receive Error %d ", __FUNCTION__, rval);
         return rval;
       }
     }
     return StartReceiving();
   }
   return kMediaConduitNoError;
 }
 
@@ -1709,32 +1713,32 @@ WebrtcVideoConduit::SelectSendResolution
     }
   }
 
   // Adapt to getUserMedia resolution changes
   // check if we need to reconfigure the sending resolution.
   // NOTE: mSendingWidth != mLastWidth, because of maxwidth/height/etc above
   bool changed = false;
   if (mSendingWidth != width || mSendingHeight != height) {
-    CSFLogDebug(logTag, "%s: resolution changing to %ux%u (from %ux%u)",
+    CSFLogDebug(LOGTAG, "%s: resolution changing to %ux%u (from %ux%u)",
                 __FUNCTION__, width, height, mSendingWidth, mSendingHeight);
     // This will avoid us continually retrying this operation if it fails.
     // If the resolution changes, we'll try again.  In the meantime, we'll
     // keep using the old size in the encoder.
     mSendingWidth = width;
     mSendingHeight = height;
     changed = true;
   }
 
   unsigned int framerate = SelectSendFrameRate(mCurSendCodecConfig,
                                                mSendingFramerate,
                                                mSendingWidth,
                                                mSendingHeight);
   if (mSendingFramerate != framerate) {
-    CSFLogDebug(logTag, "%s: framerate changing to %u (from %u)",
+    CSFLogDebug(LOGTAG, "%s: framerate changing to %u (from %u)",
                 __FUNCTION__, framerate, mSendingFramerate);
     mSendingFramerate = framerate;
     changed = true;
   }
 
   if (changed) {
     // On a resolution change, bounce this to the correct thread to
     // re-configure (same as used for Init().  Do *not* block the calling
@@ -1760,17 +1764,17 @@ WebrtcVideoConduit::SelectSendResolution
       RefPtr<Runnable> webrtc_runnable =
         media::NewRunnableFrom([self, width, height, new_frame]() -> nsresult {
             UniquePtr<webrtc::VideoFrame> local_frame(new_frame); // Simplify cleanup
 
             MutexAutoLock lock(self->mCodecMutex);
             return self->ReconfigureSendCodec(width, height, new_frame);
           });
       // new_frame now owned by lambda
-      CSFLogDebug(logTag, "%s: proxying lambda to WebRTC thread for reconfig (width %u/%u, height %u/%u",
+      CSFLogDebug(LOGTAG, "%s: proxying lambda to WebRTC thread for reconfig (width %u/%u, height %u/%u",
                   __FUNCTION__, width, mLastWidth, height, mLastHeight);
       NS_DispatchToMainThread(webrtc_runnable.forget());
       if (new_frame) {
         return true; // queued it
       }
     } else {
       // already on the right thread
       ReconfigureSendCodec(width, height, frame);
@@ -1789,17 +1793,17 @@ WebrtcVideoConduit::ReconfigureSendCodec
   // Test in case the stream hasn't started yet!  We could get a frame in
   // before we get around to StartTransmitting(), and that would dispatch a
   // runnable to call this.
   mInReconfig = false;
   if (mSendStream) {
     mSendStream->ReconfigureVideoEncoder(mEncoderConfig.CopyConfig());
     if (frame) {
       mVideoBroadcaster.OnFrame(*frame);
-      CSFLogDebug(logTag, "%s Inserted a frame from reconfig lambda", __FUNCTION__);
+      CSFLogDebug(LOGTAG, "%s Inserted a frame from reconfig lambda", __FUNCTION__);
     }
   }
   return NS_OK;
 }
 
 unsigned int
 WebrtcVideoConduit::SelectSendFrameRate(const VideoCodecConfig* codecConfig,
                                         unsigned int old_framerate,
@@ -1831,25 +1835,25 @@ WebrtcVideoConduit::SendVideoFrame(unsig
                                    unsigned int video_length,
                                    unsigned short width,
                                    unsigned short height,
                                    VideoType video_type,
                                    uint64_t capture_time)
 {
   // check for parameter sanity
   if (!video_buffer || video_length == 0 || width == 0 || height == 0) {
-    CSFLogError(logTag, "%s Invalid Parameters ", __FUNCTION__);
+    CSFLogError(LOGTAG, "%s Invalid Parameters ", __FUNCTION__);
     MOZ_ASSERT(false);
     return kMediaConduitMalformedArgument;
   }
   MOZ_ASSERT(video_type == VideoType::kVideoI420);
 
   // Transmission should be enabled before we insert any frames.
   if (!mEngineTransmitting) {
-    CSFLogError(logTag, "%s Engine not transmitting ", __FUNCTION__);
+    CSFLogError(LOGTAG, "%s Engine not transmitting ", __FUNCTION__);
     return kMediaConduitSessionNotInited;
   }
 
   // insert the frame to video engine in I420 format only
   const int stride_y = width;
   const int stride_uv = (width + 1) / 2;
 
   const uint8_t* buffer_y = video_buffer;
@@ -1870,17 +1874,17 @@ WebrtcVideoConduit::SendVideoFrame(unsig
   return SendVideoFrame(video_frame);
 }
 
 void
 WebrtcVideoConduit::AddOrUpdateSink(
   rtc::VideoSinkInterface<webrtc::VideoFrame>* sink,
   const rtc::VideoSinkWants& wants)
 {
-  CSFLogDebug(logTag, "%s (send SSRC %u (0x%x)) - wants pixels = %d/%d", __FUNCTION__,
+  CSFLogDebug(LOGTAG, "%s (send SSRC %u (0x%x)) - wants pixels = %d/%d", __FUNCTION__,
               mSendStreamConfig.rtp.ssrcs.front(), mSendStreamConfig.rtp.ssrcs.front(),
               wants.max_pixel_count ? *wants.max_pixel_count : -1,
               wants.max_pixel_count_step_up ? *wants.max_pixel_count_step_up : -1);
 
   // MUST run on the same thread as first call (MainThread)
   if (!NS_IsMainThread()) {
     // This can be asynchronous
     RefPtr<WebrtcVideoConduit> self(this);
@@ -1935,28 +1939,28 @@ WebrtcVideoConduit::OnSinkWantsChanged(
 MediaConduitErrorCode
 WebrtcVideoConduit::SendVideoFrame(webrtc::VideoFrame& frame)
 {
   // XXX Google uses a "timestamp_aligner" to translate timestamps from the
   // camera via TranslateTimestamp(); we should look at doing the same.  This
   // avoids sampling error when capturing frames, but google had to deal with some
   // broken cameras, include Logitech c920's IIRC.
 
-  CSFLogVerbose(logTag, "%s (send SSRC %u (0x%x))", __FUNCTION__,
+  CSFLogVerbose(LOGTAG, "%s (send SSRC %u (0x%x))", __FUNCTION__,
               mSendStreamConfig.rtp.ssrcs.front(), mSendStreamConfig.rtp.ssrcs.front());
   // See if we need to recalculate what we're sending.
   // Don't compute mSendingWidth/Height, since those may not be the same as the input.
   {
     MutexAutoLock lock(mCodecMutex);
     if (mInReconfig) {
       // Waiting for it to finish
       return kMediaConduitNoError;
     }
     if (frame.width() != mLastWidth || frame.height() != mLastHeight) {
-      CSFLogVerbose(logTag, "%s: call SelectSendResolution with %ux%u",
+      CSFLogVerbose(LOGTAG, "%s: call SelectSendResolution with %ux%u",
                     __FUNCTION__, frame.width(), frame.height());
       if (SelectSendResolution(frame.width(), frame.height(), &frame)) {
         // SelectSendResolution took ownership of the data in i420_frame.
         // Submit the frame after reconfig is done
         return kMediaConduitNoError;
       }
     }
     // adapt input video to wants of sink
@@ -2036,28 +2040,28 @@ WebrtcVideoConduit::SendVideoFrame(webrt
 
 // Transport Layer Callbacks
 
 MediaConduitErrorCode
 WebrtcVideoConduit::DeliverPacket(const void* data, int len)
 {
   // Media Engine should be receiving already.
   if (!mCall) {
-    CSFLogError(logTag, "Error: %s when not receiving", __FUNCTION__);
+    CSFLogError(LOGTAG, "Error: %s when not receiving", __FUNCTION__);
     return kMediaConduitSessionNotInited;
   }
 
   // XXX we need to get passed the time the packet was received
   webrtc::PacketReceiver::DeliveryStatus status =
     mCall->Call()->Receiver()->DeliverPacket(webrtc::MediaType::VIDEO,
                                              static_cast<const uint8_t*>(data),
                                              len, webrtc::PacketTime());
 
   if (status != webrtc::PacketReceiver::DELIVERY_OK) {
-    CSFLogError(logTag, "%s DeliverPacket Failed, %d", __FUNCTION__, status);
+    CSFLogError(LOGTAG, "%s DeliverPacket Failed, %d", __FUNCTION__, status);
     return kMediaConduitRTPProcessingFailed;
   }
 
   return kMediaConduitNoError;
 }
 
 MediaConduitErrorCode
 WebrtcVideoConduit::ReceivedRTPPacket(const void* data, int len, uint32_t ssrc)
@@ -2070,29 +2074,29 @@ WebrtcVideoConduit::ReceivedRTPPacket(co
   if (queue || mRecvSSRC != ssrc) {
     // capture packet for insertion after ssrc is set -- do this before
     // sending the runnable, since it may pull from this.  Since it
     // dispatches back to us, it's less critial to do this here, but doesn't
     // hurt.
     UniquePtr<QueuedPacket> packet((QueuedPacket*) malloc(sizeof(QueuedPacket) + len-1));
     packet->mLen = len;
     memcpy(packet->mData, data, len);
-    CSFLogDebug(logTag, "queuing packet: seq# %u, Len %d ",
+    CSFLogDebug(LOGTAG, "queuing packet: seq# %u, Len %d ",
                 (uint16_t)ntohs(((uint16_t*) packet->mData)[1]), packet->mLen);
     if (queue) {
       mQueuedPackets.AppendElement(Move(packet));
       return kMediaConduitNoError;
     }
     // a new switch needs to be done
     // any queued packets are from a previous switch that hasn't completed
     // yet; drop them and only process the latest SSRC
     mQueuedPackets.Clear();
     mQueuedPackets.AppendElement(Move(packet));
 
-    CSFLogDebug(logTag, "%s: switching from SSRC %u to %u", __FUNCTION__,
+    CSFLogDebug(LOGTAG, "%s: switching from SSRC %u to %u", __FUNCTION__,
                 mRecvSSRC, ssrc);
     // we "switch" here immediately, but buffer until the queue is released
     mRecvSSRC = ssrc;
     mRecvSSRCSetInProgress = true;
     queue = true;
 
     // Ensure lamba captures refs
     RefPtr<WebrtcVideoConduit> self = this;
@@ -2108,95 +2112,95 @@ WebrtcVideoConduit::ReceivedRTPPacket(co
           // errors to the PC.
           WebrtcGmpPCHandleSetter setter(self->mPCHandle);
           self->SetRemoteSSRC(ssrc); // this will likely re-create the VideoReceiveStream
           // We want to unblock the queued packets on the original thread
           thread->Dispatch(media::NewRunnableFrom([self, ssrc]() mutable {
                 if (ssrc == self->mRecvSSRC) {
                   // SSRC is set; insert queued packets
                   for (auto& packet : self->mQueuedPackets) {
-                    CSFLogDebug(logTag, "Inserting queued packets: seq# %u, Len %d ",
+                    CSFLogDebug(LOGTAG, "Inserting queued packets: seq# %u, Len %d ",
                                 (uint16_t)ntohs(((uint16_t*) packet->mData)[1]), packet->mLen);
 
                     if (self->DeliverPacket(packet->mData, packet->mLen) != kMediaConduitNoError) {
-                      CSFLogError(logTag, "%s RTP Processing Failed", __FUNCTION__);
+                      CSFLogError(LOGTAG, "%s RTP Processing Failed", __FUNCTION__);
                       // Keep delivering and then clear the queue
                     }
                   }
                   self->mQueuedPackets.Clear();
                   // we don't leave inprogress until there are no changes in-flight
                   self->mRecvSSRCSetInProgress = false;
                 }
                 // else this is an intermediate switch; another is in-flight
 
                 return NS_OK;
               }), NS_DISPATCH_NORMAL);
           return NS_OK;
         }));
     return kMediaConduitNoError;
   }
 
-  CSFLogVerbose(logTag, "%s: seq# %u, Len %d, SSRC %u (0x%x) ", __FUNCTION__,
+  CSFLogVerbose(LOGTAG, "%s: seq# %u, Len %d, SSRC %u (0x%x) ", __FUNCTION__,
                 (uint16_t)ntohs(((uint16_t*) data)[1]), len,
                 (uint32_t) ntohl(((uint32_t*) data)[2]),
                 (uint32_t) ntohl(((uint32_t*) data)[2]));
 
   if (DeliverPacket(data, len) != kMediaConduitNoError) {
-    CSFLogError(logTag, "%s RTP Processing Failed", __FUNCTION__);
+    CSFLogError(LOGTAG, "%s RTP Processing Failed", __FUNCTION__);
     return kMediaConduitRTPProcessingFailed;
   }
   return kMediaConduitNoError;
 }
 
 MediaConduitErrorCode
 WebrtcVideoConduit::ReceivedRTCPPacket(const void* data, int len)
 {
-  CSFLogVerbose(logTag, " %s Len %d ", __FUNCTION__, len);
+  CSFLogVerbose(LOGTAG, " %s Len %d ", __FUNCTION__, len);
 
   if (DeliverPacket(data, len) != kMediaConduitNoError) {
-    CSFLogError(logTag, "%s RTCP Processing Failed", __FUNCTION__);
+    CSFLogError(LOGTAG, "%s RTCP Processing Failed", __FUNCTION__);
     return kMediaConduitRTPProcessingFailed;
   }
 
   return kMediaConduitNoError;
 }
 
 MediaConduitErrorCode
 WebrtcVideoConduit::StopTransmitting()
 {
   if (mEngineTransmitting) {
     {
       MutexAutoLock lock(mCodecMutex);
       if (mSendStream) {
-          CSFLogDebug(logTag, "%s Engine Already Sending. Attemping to Stop ", __FUNCTION__);
+          CSFLogDebug(LOGTAG, "%s Engine Already Sending. Attemping to Stop ", __FUNCTION__);
           mSendStream->Stop();
       }
     }
 
     mEngineTransmitting = false;
   }
   return kMediaConduitNoError;
 }
 
 MediaConduitErrorCode
 WebrtcVideoConduit::StartTransmitting()
 {
   if (mEngineTransmitting) {
     return kMediaConduitNoError;
   }
 
-  CSFLogDebug(logTag, "%s Attemping to start... ", __FUNCTION__);
+  CSFLogDebug(LOGTAG, "%s Attemping to start... ", __FUNCTION__);
   {
     // Start Transmitting on the video engine
     MutexAutoLock lock(mCodecMutex);
 
     if (!mSendStream) {
       MediaConduitErrorCode rval = CreateSendStream();
       if (rval != kMediaConduitNoError) {
-        CSFLogError(logTag, "%s Start Send Error %d ", __FUNCTION__, rval);
+        CSFLogError(LOGTAG, "%s Start Send Error %d ", __FUNCTION__, rval);
         return rval;
       }
     }
 
     mSendStream->Start();
     // XXX File a bug to consider hooking this up to the state of mtransport
     mCall->Call()->SignalChannelNetworkState(webrtc::MediaType::VIDEO, webrtc::kNetworkUp);
     mEngineTransmitting = true;
@@ -2207,32 +2211,32 @@ WebrtcVideoConduit::StartTransmitting()
 
 MediaConduitErrorCode
 WebrtcVideoConduit::StopReceiving()
 {
   NS_ASSERTION(NS_IsMainThread(), "Only call on main thread");
   // Are we receiving already? If so, stop receiving and playout
   // since we can't apply new recv codec when the engine is playing.
   if (mEngineReceiving && mRecvStream) {
-    CSFLogDebug(logTag, "%s Engine Already Receiving . Attemping to Stop ", __FUNCTION__);
+    CSFLogDebug(LOGTAG, "%s Engine Already Receiving . Attemping to Stop ", __FUNCTION__);
     mRecvStream->Stop();
   }
 
   mEngineReceiving = false;
   return kMediaConduitNoError;
 }
 
 MediaConduitErrorCode
 WebrtcVideoConduit::StartReceiving()
 {
   if (mEngineReceiving) {
     return kMediaConduitNoError;
   }
 
-  CSFLogDebug(logTag, "%s Attemping to start... (SSRC %u (0x%x))", __FUNCTION__, mRecvSSRC, mRecvSSRC);
+  CSFLogDebug(LOGTAG, "%s Attemping to start... (SSRC %u (0x%x))", __FUNCTION__, mRecvSSRC, mRecvSSRC);
   {
     // Start Receive on the video engine
     MutexAutoLock lock(mCodecMutex);
     MOZ_ASSERT(mRecvStream);
 
     mRecvStream->Start();
     // XXX File a bug to consider hooking this up to the state of mtransport
     mCall->Call()->SignalChannelNetworkState(webrtc::MediaType::VIDEO, webrtc::kNetworkUp);
@@ -2246,67 +2250,67 @@ WebrtcVideoConduit::StartReceiving()
 // Called on MSG thread
 bool
 WebrtcVideoConduit::SendRtp(const uint8_t* packet, size_t length,
                             const webrtc::PacketOptions& options)
 {
   // XXX(pkerr) - PacketOptions possibly containing RTP extensions are ignored.
   // The only field in it is the packet_id, which is used when the header
   // extension for TransportSequenceNumber is being used, which we don't.
-  CSFLogVerbose(logTag, "%s Sent RTP Packet seq %d, len %lu, SSRC %u (0x%x)",
+  CSFLogVerbose(LOGTAG, "%s Sent RTP Packet seq %d, len %lu, SSRC %u (0x%x)",
                 __FUNCTION__,
                 (uint16_t) ntohs(*((uint16_t*) &packet[2])),
                 (unsigned long)length,
                 (uint32_t) ntohl(*((uint32_t*) &packet[8])),
                 (uint32_t) ntohl(*((uint32_t*) &packet[8])));
 
   ReentrantMonitorAutoEnter enter(mTransportMonitor);
   if (!mTransmitterTransport ||
      NS_FAILED(mTransmitterTransport->SendRtpPacket(packet, length)))
   {
-    CSFLogError(logTag, "%s RTP Packet Send Failed ", __FUNCTION__);
+    CSFLogError(LOGTAG, "%s RTP Packet Send Failed ", __FUNCTION__);
     return false;
   }
   return true;
 }
 
 // Called from multiple threads including webrtc Process thread
 bool
 WebrtcVideoConduit::SendRtcp(const uint8_t* packet, size_t length)
 {
-  CSFLogVerbose(logTag, "%s : len %lu ", __FUNCTION__, (unsigned long)length);
+  CSFLogVerbose(LOGTAG, "%s : len %lu ", __FUNCTION__, (unsigned long)length);
   // We come here if we have only one pipeline/conduit setup,
   // such as for unidirectional streams.
   // We also end up here if we are receiving
   ReentrantMonitorAutoEnter enter(mTransportMonitor);
   if (mReceiverTransport &&
       NS_SUCCEEDED(mReceiverTransport->SendRtcpPacket(packet, length)))
   {
     // Might be a sender report, might be a receiver report, we don't know.
-    CSFLogDebug(logTag, "%s Sent RTCP Packet ", __FUNCTION__);
+    CSFLogDebug(LOGTAG, "%s Sent RTCP Packet ", __FUNCTION__);
     return true;
   }
   if (mTransmitterTransport &&
              NS_SUCCEEDED(mTransmitterTransport->SendRtcpPacket(packet, length))) {
     return true;
   }
 
-  CSFLogError(logTag, "%s RTCP Packet Send Failed ", __FUNCTION__);
+  CSFLogError(LOGTAG, "%s RTCP Packet Send Failed ", __FUNCTION__);
   return false;
 }
 
 void
 WebrtcVideoConduit::OnFrame(const webrtc::VideoFrame& video_frame)
 {
-  CSFLogVerbose(logTag, "%s: recv SSRC %u (0x%x), size %ux%u", __FUNCTION__,
+  CSFLogVerbose(LOGTAG, "%s: recv SSRC %u (0x%x), size %ux%u", __FUNCTION__,
                 mRecvSSRC, mRecvSSRC, video_frame.width(), video_frame.height());
   ReentrantMonitorAutoEnter enter(mTransportMonitor);
 
   if (!mRenderer) {
-    CSFLogError(logTag, "%s Renderer is NULL  ", __FUNCTION__);
+    CSFLogError(LOGTAG, "%s Renderer is NULL  ", __FUNCTION__);
     return;
   }
 
   if (mReceivingWidth != video_frame.width() ||
       mReceivingHeight != video_frame.height()) {
     mReceivingWidth = video_frame.width();
     mReceivingHeight = video_frame.height();
     mRenderer->FrameSizeChange(mReceivingWidth, mReceivingHeight, mNumReceivingStreams);
@@ -2356,37 +2360,37 @@ WebrtcVideoConduit::CodecsDifferent(cons
 /**
  * Perform validation on the codecConfig to be applied
  * Verifies if the codec is already applied.
  */
 MediaConduitErrorCode
 WebrtcVideoConduit::ValidateCodecConfig(const VideoCodecConfig* codecInfo)
 {
   if(!codecInfo) {
-    CSFLogError(logTag, "%s Null CodecConfig ", __FUNCTION__);
+    CSFLogError(LOGTAG, "%s Null CodecConfig ", __FUNCTION__);
     return kMediaConduitMalformedArgument;
   }
 
   if((codecInfo->mName.empty()) ||
      (codecInfo->mName.length() >= CODEC_PLNAME_SIZE)) {
-    CSFLogError(logTag, "%s Invalid Payload Name Length ", __FUNCTION__);
+    CSFLogError(LOGTAG, "%s Invalid Payload Name Length ", __FUNCTION__);
     return kMediaConduitMalformedArgument;
   }
 
   return kMediaConduitNoError;
 }
 
 void
 WebrtcVideoConduit::DumpCodecDB() const
 {
   for (auto& entry : mRecvCodecList) {
-    CSFLogDebug(logTag, "Payload Name: %s", entry->mName.c_str());
-    CSFLogDebug(logTag, "Payload Type: %d", entry->mType);
-    CSFLogDebug(logTag, "Payload Max Frame Size: %d", entry->mEncodingConstraints.maxFs);
-    CSFLogDebug(logTag, "Payload Max Frame Rate: %d", entry->mEncodingConstraints.maxFps);
+    CSFLogDebug(LOGTAG, "Payload Name: %s", entry->mName.c_str());
+    CSFLogDebug(LOGTAG, "Payload Type: %d", entry->mType);
+    CSFLogDebug(LOGTAG, "Payload Max Frame Size: %d", entry->mEncodingConstraints.maxFs);
+    CSFLogDebug(LOGTAG, "Payload Max Frame Rate: %d", entry->mEncodingConstraints.maxFps);
   }
 }
 
 void
 WebrtcVideoConduit::VideoLatencyUpdate(uint64_t newSample)
 {
   mVideoLatencyAvg = (sRoundingPadding * newSample + sAlphaNum * mVideoLatencyAvg) / sAlphaDen;
 }
--- a/media/webrtc/signaling/src/media-conduit/WebrtcMediaCodecVP8VideoCodec.cpp
+++ b/media/webrtc/signaling/src/media-conduit/WebrtcMediaCodecVP8VideoCodec.cpp
@@ -35,67 +35,71 @@ using namespace mozilla;
 using namespace mozilla::java;
 using namespace mozilla::java::sdk;
 
 static const int32_t DECODER_TIMEOUT = 10 * PR_USEC_PER_MSEC; // 10ms
 static const char MEDIACODEC_VIDEO_MIME_VP8[] = "video/x-vnd.on2.vp8";
 
 namespace mozilla {
 
-static const char* logTag ="WebrtcMediaCodecVP8VideoCodec";
+static const char* wmcLogTag ="WebrtcMediaCodecVP8VideoCodec";
+#ifdef LOGTAG
+#undef LOGTAG
+#endif
+#define LOGTAG wmcLogTag
 
 class CallbacksSupport final : public JavaCallbacksSupport
 {
 public:
   CallbacksSupport(webrtc::EncodedImageCallback* aCallback)
     : mCallback(aCallback)
     , mCritSect(webrtc::CriticalSectionWrapper::CreateCriticalSection())
     , mPictureId(0) {
-    CSFLogDebug(logTag,  "%s %p", __FUNCTION__, this);
+    CSFLogDebug(LOGTAG,  "%s %p", __FUNCTION__, this);
     memset(&mEncodedImage, 0, sizeof(mEncodedImage));
   }
 
   ~CallbacksSupport() {
-    CSFLogDebug(logTag,  "%s %p", __FUNCTION__, this);
+    CSFLogDebug(LOGTAG,  "%s %p", __FUNCTION__, this);
     if (mEncodedImage._size) {
       delete [] mEncodedImage._buffer;
       mEncodedImage._buffer = nullptr;
       mEncodedImage._size = 0;
     }
   }
 
   void VerifyAndAllocate(const uint32_t minimumSize)
   {
-    CSFLogDebug(logTag,  "%s %p", __FUNCTION__, this);
+    CSFLogDebug(LOGTAG,  "%s %p", __FUNCTION__, this);
     if(minimumSize > mEncodedImage._size)
     {
         uint8_t* newBuffer = new uint8_t[minimumSize];
         MOZ_RELEASE_ASSERT(newBuffer);
 
         if(mEncodedImage._buffer) {
             delete [] mEncodedImage._buffer;
         }
         mEncodedImage._buffer = newBuffer;
         mEncodedImage._size = minimumSize;
     }
   }
 
   void HandleInput(jlong aTimestamp, bool aProcessed) override
   {
-    CSFLogDebug(logTag,  "%s %p", __FUNCTION__, this);
+    CSFLogDebug(LOGTAG,  "%s %p", __FUNCTION__, this);
   }
 
   void HandleOutputFormatChanged(MediaFormat::Param aFormat) override
   {
-    CSFLogDebug(logTag,  "%s %p", __FUNCTION__, this);
+    CSFLogDebug(LOGTAG,  "%s %p", __FUNCTION__, this);
   }
 
   void HandleOutput(Sample::Param aSample)
   {
-    CSFLogDebug(logTag,  "%s %p", __FUNCTION__, this);
+    CSFLogDebug(LOGTAG,  "%s %p", __FUNCTION__, this);
     BufferInfo::LocalRef info = aSample->Info();
 
     int32_t size;
     bool ok = NS_SUCCEEDED(info->Size(&size));
     MOZ_RELEASE_ASSERT(ok);
 
     if (size > 0) {
       webrtc::CriticalSectionScoped lock(mCritSect.get());
@@ -140,17 +144,17 @@ public:
 
       MOZ_RELEASE_ASSERT(mCallback);
       mCallback->OnEncodedImage(mEncodedImage, &info, &header);
     }
   }
 
   void HandleError(const MediaResult& aError) override
   {
-    CSFLogDebug(logTag,  "%s %p", __FUNCTION__, this);
+    CSFLogDebug(LOGTAG,  "%s %p", __FUNCTION__, this);
   }
 
   friend class WebrtcMediaCodecVP8VideoRemoteEncoder;
 
 private:
   webrtc::EncodedImageCallback* mCallback;
   Atomic<bool> mCanceled;
   webrtc::EncodedImage mEncodedImage;
@@ -289,96 +293,96 @@ private:
 
 class WebrtcAndroidMediaCodec {
 public:
   WebrtcAndroidMediaCodec()
     : mEncoderCallback(nullptr)
     , mDecoderCallback(nullptr)
     , isStarted(false)
     , mEnding(false) {
-    CSFLogDebug(logTag,  "%s ", __FUNCTION__);
+    CSFLogDebug(LOGTAG,  "%s ", __FUNCTION__);
   }
 
   nsresult Configure(uint32_t width,
                      uint32_t height,
                      const jobject aSurface,
                      uint32_t flags,
                      const char* mime,
                      bool encoder) {
-    CSFLogDebug(logTag,  "%s ", __FUNCTION__);
+    CSFLogDebug(LOGTAG,  "%s ", __FUNCTION__);
     nsresult res = NS_OK;
 
     if (!mCoder) {
       mWidth = width;
       mHeight = height;
 
       MediaFormat::LocalRef format;
 
       res = MediaFormat::CreateVideoFormat(nsCString(mime),
                                      mWidth,
                                      mHeight,
                                      &format);
 
       if (NS_FAILED(res)) {
-        CSFLogDebug(logTag, "WebrtcAndroidMediaCodec::%s, CreateVideoFormat failed err = %d", __FUNCTION__, (int)res);
+        CSFLogDebug(LOGTAG, "WebrtcAndroidMediaCodec::%s, CreateVideoFormat failed err = %d", __FUNCTION__, (int)res);
         return NS_ERROR_FAILURE;
       }
 
       if (encoder) {
         mCoder = CreateEncoder(mime);
 
         if (NS_FAILED(res)) {
-          CSFLogDebug(logTag, "WebrtcAndroidMediaCodec::%s, CreateEncoderByType failed err = %d", __FUNCTION__, (int)res);
+          CSFLogDebug(LOGTAG, "WebrtcAndroidMediaCodec::%s, CreateEncoderByType failed err = %d", __FUNCTION__, (int)res);
           return NS_ERROR_FAILURE;
         }
 
         res = format->SetInteger(MediaFormat::KEY_BIT_RATE, 1000*300);
         res = format->SetInteger(MediaFormat::KEY_BITRATE_MODE, 2);
         res = format->SetInteger(MediaFormat::KEY_COLOR_FORMAT, 21);
         res = format->SetInteger(MediaFormat::KEY_FRAME_RATE, 30);
         res = format->SetInteger(MediaFormat::KEY_I_FRAME_INTERVAL, 100);
 
       } else {
         mCoder = CreateDecoder(mime);
         if (NS_FAILED(res)) {
-          CSFLogDebug(logTag, "WebrtcAndroidMediaCodec::%s, CreateDecoderByType failed err = %d", __FUNCTION__, (int)res);
+          CSFLogDebug(LOGTAG, "WebrtcAndroidMediaCodec::%s, CreateDecoderByType failed err = %d", __FUNCTION__, (int)res);
           return NS_ERROR_FAILURE;
         }
       }
       res = mCoder->Configure(format, nullptr, nullptr, flags);
       if (NS_FAILED(res)) {
-        CSFLogDebug(logTag, "WebrtcAndroidMediaCodec::%s, err = %d", __FUNCTION__, (int)res);
+        CSFLogDebug(LOGTAG, "WebrtcAndroidMediaCodec::%s, err = %d", __FUNCTION__, (int)res);
       }
     }
 
     return res;
   }
 
   nsresult Start() {
-    CSFLogDebug(logTag,  "%s ", __FUNCTION__);
+    CSFLogDebug(LOGTAG,  "%s ", __FUNCTION__);
 
     if (!mCoder) {
       return NS_ERROR_FAILURE;
     }
 
     mEnding = false;
 
     nsresult res;
     res = mCoder->Start();
     if (NS_FAILED(res)) {
-      CSFLogDebug(logTag, "WebrtcAndroidMediaCodec::%s, mCoder->start() return err = %d",
+      CSFLogDebug(LOGTAG, "WebrtcAndroidMediaCodec::%s, mCoder->start() return err = %d",
                   __FUNCTION__, (int)res);
       return res;
     }
     isStarted = true;
     return NS_OK;
   }
 
   nsresult Stop() {
-    CSFLogDebug(logTag,  "%s ", __FUNCTION__);
+    CSFLogDebug(LOGTAG,  "%s ", __FUNCTION__);
     mEnding = true;
 
     if (mOutputDrain != nullptr) {
       mOutputDrain->Stop();
       mOutputDrain = nullptr;
     }
 
     mCoder->Stop();
@@ -386,17 +390,17 @@ public:
     isStarted = false;
     return NS_OK;
   }
 
   void GenerateVideoFrame(
       size_t width, size_t height, uint32_t timeStamp,
       void* decoded, int color_format) {
 
-    CSFLogDebug(logTag,  "%s ", __FUNCTION__);
+    CSFLogDebug(LOGTAG,  "%s ", __FUNCTION__);
 
     // TODO: eliminate extra pixel copy/color conversion
     size_t widthUV = (width + 1) / 2;
     rtc::scoped_refptr<webrtc::I420Buffer> buffer;
     buffer = webrtc::I420Buffer::Create(width, height, width, widthUV, widthUV);
 
     uint8_t* src_nv12 = static_cast<uint8_t *>(decoded);
     int src_nv12_y_size = width * height;
@@ -418,40 +422,40 @@ public:
 
   int32_t
   FeedMediaCodecInput(
       const webrtc::EncodedImage& inputImage,
       int64_t renderTimeMs) {
 
 #ifdef WEBRTC_MEDIACODEC_DEBUG
     uint32_t time = PR_IntervalNow();
-    CSFLogDebug(logTag,  "%s ", __FUNCTION__);
+    CSFLogDebug(LOGTAG,  "%s ", __FUNCTION__);
 #endif
 
     int inputIndex = DequeueInputBuffer(DECODER_TIMEOUT);
     if (inputIndex == -1) {
-      CSFLogError(logTag,  "%s equeue input buffer failed", __FUNCTION__);
+      CSFLogError(LOGTAG,  "%s equeue input buffer failed", __FUNCTION__);
       return inputIndex;
     }
 
 #ifdef WEBRTC_MEDIACODEC_DEBUG
-    CSFLogDebug(logTag,  "%s dequeue input buffer took %u ms", __FUNCTION__, PR_IntervalToMilliseconds(PR_IntervalNow()-time));
+    CSFLogDebug(LOGTAG,  "%s dequeue input buffer took %u ms", __FUNCTION__, PR_IntervalToMilliseconds(PR_IntervalNow()-time));
     time = PR_IntervalNow();
 #endif
 
     size_t size = inputImage._length;
 
     JNIEnv* env = jsjni_GetJNIForThread();
     jobject buffer = env->GetObjectArrayElement(mInputBuffers, inputIndex);
     void* directBuffer = env->GetDirectBufferAddress(buffer);
 
     PodCopy((uint8_t*)directBuffer, inputImage._buffer, size);
 
     if (inputIndex >= 0) {
-      CSFLogError(logTag,  "%s queue input buffer inputIndex = %d", __FUNCTION__, inputIndex);
+      CSFLogError(LOGTAG,  "%s queue input buffer inputIndex = %d", __FUNCTION__, inputIndex);
       QueueInputBuffer(inputIndex, 0, size, renderTimeMs, 0);
 
       {
         if (mOutputDrain == nullptr) {
           mOutputDrain = new OutputDrain(this);
           mOutputDrain->Start();
         }
         EncodedFrame frame;
@@ -476,38 +480,38 @@ public:
 
 #ifdef WEBRTC_MEDIACODEC_DEBUG
     uint32_t time = PR_IntervalNow();
 #endif
     nsresult res;
     BufferInfo::LocalRef bufferInfo;
     res = BufferInfo::New(&bufferInfo);
     if (NS_FAILED(res)) {
-      CSFLogDebug(logTag, "WebrtcAndroidMediaCodec::%s, BufferInfo::New return err = %d",
+      CSFLogDebug(LOGTAG, "WebrtcAndroidMediaCodec::%s, BufferInfo::New return err = %d",
                   __FUNCTION__, (int)res);
       return res;
     }
     int32_t outputIndex = DequeueOutputBuffer(bufferInfo);
 
     if (outputIndex == MediaCodec::INFO_TRY_AGAIN_LATER) {
       // Not an error: output not available yet. Try later.
-      CSFLogDebug(logTag,  "%s dequeue output buffer try again:%d", __FUNCTION__, outputIndex);
+      CSFLogDebug(LOGTAG,  "%s dequeue output buffer try again:%d", __FUNCTION__, outputIndex);
     } else if (outputIndex == MediaCodec::INFO_OUTPUT_FORMAT_CHANGED) {
       // handle format change
-      CSFLogDebug(logTag,  "%s dequeue output buffer format changed:%d", __FUNCTION__, outputIndex);
+      CSFLogDebug(LOGTAG,  "%s dequeue output buffer format changed:%d", __FUNCTION__, outputIndex);
     } else if (outputIndex == MediaCodec::INFO_OUTPUT_BUFFERS_CHANGED) {
-      CSFLogDebug(logTag,  "%s dequeue output buffer changed:%d", __FUNCTION__, outputIndex);
+      CSFLogDebug(LOGTAG,  "%s dequeue output buffer changed:%d", __FUNCTION__, outputIndex);
       GetOutputBuffers();
     } else if (outputIndex < 0) {
-      CSFLogDebug(logTag,  "%s dequeue output buffer unknow error:%d", __FUNCTION__, outputIndex);
+      CSFLogDebug(LOGTAG,  "%s dequeue output buffer unknow error:%d", __FUNCTION__, outputIndex);
       MonitorAutoLock lock(aMonitor);
       aInputFrames.pop();
     } else {
 #ifdef WEBRTC_MEDIACODEC_DEBUG
-      CSFLogDebug(logTag,  "%s dequeue output buffer# return status is %d took %u ms", __FUNCTION__, outputIndex, PR_IntervalToMilliseconds(PR_IntervalNow()-time));
+      CSFLogDebug(LOGTAG,  "%s dequeue output buffer# return status is %d took %u ms", __FUNCTION__, outputIndex, PR_IntervalToMilliseconds(PR_IntervalNow()-time));
 #endif
       EncodedFrame frame;
       {
         MonitorAutoLock lock(aMonitor);
         frame = aInputFrames.front();
         aInputFrames.pop();
       }
 
@@ -519,58 +523,58 @@ public:
       JNIEnv* env = jsjni_GetJNIForThread();
       jobject buffer = env->GetObjectArrayElement(mOutputBuffers, outputIndex);
       if (buffer) {
         // The buffer will be null on Android L if we are decoding to a Surface
         void* directBuffer = env->GetDirectBufferAddress(buffer);
 
         int color_format = 0;
 
-        CSFLogDebug(logTag,  "%s generate video frame, width = %d, height = %d, timeStamp_ = %d", __FUNCTION__, frame.width_, frame.height_, frame.timeStamp_);
+        CSFLogDebug(LOGTAG,  "%s generate video frame, width = %d, height = %d, timeStamp_ = %d", __FUNCTION__, frame.width_, frame.height_, frame.timeStamp_);
         GenerateVideoFrame(frame.width_, frame.height_, frame.timeStamp_, directBuffer, color_format);
         mDecoderCallback->Decoded(*mVideoFrame);
 
         ReleaseOutputBuffer(outputIndex, false);
         env->DeleteLocalRef(buffer);
       }
     }
     return NS_OK;
   }
 
   int32_t DequeueInputBuffer(int64_t time) {
     nsresult res;
     int32_t inputIndex;
     res = mCoder->DequeueInputBuffer(time, &inputIndex);
 
     if (NS_FAILED(res)) {
-      CSFLogDebug(logTag, "WebrtcAndroidMediaCodec::%s, mCoder->DequeueInputBuffer() return err = %d",
+      CSFLogDebug(LOGTAG, "WebrtcAndroidMediaCodec::%s, mCoder->DequeueInputBuffer() return err = %d",
                   __FUNCTION__, (int)res);
       return -1;
     }
     return inputIndex;
   }
 
   void QueueInputBuffer(int32_t inputIndex, int32_t offset, size_t size, int64_t renderTimes, int32_t flags) {
     nsresult res = NS_OK;
     res = mCoder->QueueInputBuffer(inputIndex, offset, size, renderTimes, flags);
 
     if (NS_FAILED(res)) {
-      CSFLogDebug(logTag, "WebrtcAndroidMediaCodec::%s, mCoder->QueueInputBuffer() return err = %d",
+      CSFLogDebug(LOGTAG, "WebrtcAndroidMediaCodec::%s, mCoder->QueueInputBuffer() return err = %d",
                   __FUNCTION__, (int)res);
     }
   }
 
   int32_t DequeueOutputBuffer(BufferInfo::Param aInfo) {
     nsresult res;
 
     int32_t outputStatus;
     res = mCoder->DequeueOutputBuffer(aInfo, DECODER_TIMEOUT, &outputStatus);
 
     if (NS_FAILED(res)) {
-      CSFLogDebug(logTag, "WebrtcAndroidMediaCodec::%s, mCoder->DequeueOutputBuffer() return err = %d",
+      CSFLogDebug(LOGTAG, "WebrtcAndroidMediaCodec::%s, mCoder->DequeueOutputBuffer() return err = %d",
                   __FUNCTION__, (int)res);
       return -1;
     }
 
     return outputStatus;
   }
 
   void ReleaseOutputBuffer(int32_t index, bool flag) {
@@ -584,17 +588,17 @@ public:
       env->DeleteGlobalRef(mInputBuffers);
     }
 
     nsresult res;
     jni::ObjectArray::LocalRef inputBuffers;
     res = mCoder->GetInputBuffers(&inputBuffers);
     mInputBuffers = (jobjectArray) env->NewGlobalRef(inputBuffers.Get());
     if (NS_FAILED(res)) {
-      CSFLogDebug(logTag, "WebrtcAndroidMediaCodec::%s, GetInputBuffers return err = %d",
+      CSFLogDebug(LOGTAG, "WebrtcAndroidMediaCodec::%s, GetInputBuffers return err = %d",
                   __FUNCTION__, (int)res);
       return nullptr;
     }
 
     return mInputBuffers;
   }
 
   jobjectArray GetOutputBuffers() {
@@ -604,17 +608,17 @@ public:
       env->DeleteGlobalRef(mOutputBuffers);
     }
 
     nsresult res;
     jni::ObjectArray::LocalRef outputBuffers;
     res = mCoder->GetOutputBuffers(&outputBuffers);
     mOutputBuffers = (jobjectArray) env->NewGlobalRef(outputBuffers.Get());
     if (NS_FAILED(res)) {
-      CSFLogDebug(logTag, "WebrtcAndroidMediaCodec::%s, GetOutputBuffers return err = %d",
+      CSFLogDebug(LOGTAG, "WebrtcAndroidMediaCodec::%s, GetOutputBuffers return err = %d",
                   __FUNCTION__, (int)res);
       return nullptr;
     }
 
     return mOutputBuffers;
   }
 
   void SetDecoderCallback(webrtc::DecodedImageCallback* aCallback) {
@@ -693,17 +697,17 @@ static bool I420toNV12(uint8_t* dstY, ui
                                        inputImage.height());
   return converted;
 }
 
 // Encoder.
 WebrtcMediaCodecVP8VideoEncoder::WebrtcMediaCodecVP8VideoEncoder()
   : mCallback(nullptr)
   , mMediaCodecEncoder(nullptr) {
-  CSFLogDebug(logTag,  "%s ", __FUNCTION__);
+  CSFLogDebug(LOGTAG,  "%s ", __FUNCTION__);
 
   memset(&mEncodedImage, 0, sizeof(mEncodedImage));
 }
 
 bool WebrtcMediaCodecVP8VideoEncoder::ResetInputBuffers() {
   mInputBuffers = mMediaCodecEncoder->GetInputBuffers();
 
   if (!mInputBuffers)
@@ -742,26 +746,26 @@ WebrtcMediaCodecVP8VideoEncoder::VerifyA
     return 0;
 }
 
 int32_t WebrtcMediaCodecVP8VideoEncoder::InitEncode(
     const webrtc::VideoCodec* codecSettings,
     int32_t numberOfCores,
     size_t maxPayloadSize) {
   mMaxPayloadSize = maxPayloadSize;
-  CSFLogDebug(logTag,  "%s, w = %d, h = %d", __FUNCTION__, codecSettings->width, codecSettings->height);
+  CSFLogDebug(LOGTAG,  "%s, w = %d, h = %d", __FUNCTION__, codecSettings->width, codecSettings->height);
 
   return WEBRTC_VIDEO_CODEC_OK;
 }
 
 int32_t WebrtcMediaCodecVP8VideoEncoder::Encode(
     const webrtc::VideoFrame& inputImage,
     const webrtc::CodecSpecificInfo* codecSpecificInfo,
     const std::vector<webrtc::FrameType>* frame_types) {
-  CSFLogDebug(logTag,  "%s, w = %d, h = %d", __FUNCTION__, inputImage.width(), inputImage.height());
+  CSFLogDebug(LOGTAG,  "%s, w = %d, h = %d", __FUNCTION__, inputImage.width(), inputImage.height());
 
   if (!mMediaCodecEncoder) {
     mMediaCodecEncoder = new WebrtcAndroidMediaCodec();
   }
 
   if (!mMediaCodecEncoder->isStarted) {
     if (inputImage.width() == 0 || inputImage.height() == 0) {
       return WEBRTC_VIDEO_CODEC_ERROR;
@@ -769,37 +773,37 @@ int32_t WebrtcMediaCodecVP8VideoEncoder:
       mFrameWidth = inputImage.width();
       mFrameHeight = inputImage.height();
     }
 
     mMediaCodecEncoder->SetEncoderCallback(mCallback);
     nsresult res = mMediaCodecEncoder->Configure(mFrameWidth, mFrameHeight, nullptr, MediaCodec::CONFIGURE_FLAG_ENCODE, MEDIACODEC_VIDEO_MIME_VP8, true /* encoder */);
 
     if (res != NS_OK) {
-      CSFLogDebug(logTag,  "%s, encoder configure return err = %d",
+      CSFLogDebug(LOGTAG,  "%s, encoder configure return err = %d",
                   __FUNCTION__, (int)res);
       return WEBRTC_VIDEO_CODEC_ERROR;
     }
 
     res = mMediaCodecEncoder->Start();
 
     if (NS_FAILED(res)) {
       mMediaCodecEncoder->isStarted = false;
-      CSFLogDebug(logTag,  "%s start encoder. err = %d", __FUNCTION__, (int)res);
+      CSFLogDebug(LOGTAG,  "%s start encoder. err = %d", __FUNCTION__, (int)res);
       return WEBRTC_VIDEO_CODEC_ERROR;
     }
 
     bool retBool = ResetInputBuffers();
     if (!retBool) {
-      CSFLogDebug(logTag,  "%s ResetInputBuffers failed.", __FUNCTION__);
+      CSFLogDebug(LOGTAG,  "%s ResetInputBuffers failed.", __FUNCTION__);
       return WEBRTC_VIDEO_CODEC_ERROR;
     }
     retBool = ResetOutputBuffers();
     if (!retBool) {
-      CSFLogDebug(logTag,  "%s ResetOutputBuffers failed.", __FUNCTION__);
+      CSFLogDebug(LOGTAG,  "%s ResetOutputBuffers failed.", __FUNCTION__);
       return WEBRTC_VIDEO_CODEC_ERROR;
     }
 
     mMediaCodecEncoder->isStarted = true;
   }
 
 #ifdef WEBRTC_MEDIACODEC_DEBUG
   uint32_t time = PR_IntervalNow();
@@ -807,79 +811,79 @@ int32_t WebrtcMediaCodecVP8VideoEncoder:
 
   rtc::scoped_refptr<webrtc::VideoFrameBuffer> inputBuffer = inputImage.video_frame_buffer();
   size_t sizeY = inputImage.height() * inputBuffer->StrideY();
   size_t sizeUV = ((inputImage.height() + 1)/2) * inputBuffer->StrideU();
   size_t size = sizeY + 2 * sizeUV;
 
   int inputIndex = mMediaCodecEncoder->DequeueInputBuffer(DECODER_TIMEOUT);
   if (inputIndex == -1) {
-    CSFLogError(logTag,  "%s dequeue input buffer failed", __FUNCTION__);
+    CSFLogError(LOGTAG,  "%s dequeue input buffer failed", __FUNCTION__);
     return inputIndex;
   }
 
 #ifdef WEBRTC_MEDIACODEC_DEBUG
-  CSFLogDebug(logTag,  "%s WebrtcMediaCodecVP8VideoEncoder::Encode() dequeue OMX input buffer took %u ms", __FUNCTION__, PR_IntervalToMilliseconds(PR_IntervalNow()-time));
+  CSFLogDebug(LOGTAG,  "%s WebrtcMediaCodecVP8VideoEncoder::Encode() dequeue OMX input buffer took %u ms", __FUNCTION__, PR_IntervalToMilliseconds(PR_IntervalNow()-time));
 #endif
 
   if (inputIndex >= 0) {
     JNIEnv* env = jsjni_GetJNIForThread();
     jobject buffer = env->GetObjectArrayElement(mInputBuffers, inputIndex);
     void* directBuffer = env->GetDirectBufferAddress(buffer);
 
     uint8_t* dstY = static_cast<uint8_t*>(directBuffer);
     uint16_t* dstUV = reinterpret_cast<uint16_t*>(dstY + sizeY);
 
     bool converted = I420toNV12(dstY, dstUV, inputImage);
     if (!converted) {
-      CSFLogError(logTag,  "%s WebrtcMediaCodecVP8VideoEncoder::Encode() convert input buffer to NV12 error.", __FUNCTION__);
+      CSFLogError(LOGTAG,  "%s WebrtcMediaCodecVP8VideoEncoder::Encode() convert input buffer to NV12 error.", __FUNCTION__);
       return WEBRTC_VIDEO_CODEC_ERROR;
     }
 
     env->DeleteLocalRef(buffer);
 
 #ifdef WEBRTC_MEDIACODEC_DEBUG
     time = PR_IntervalNow();
-    CSFLogError(logTag,  "%s queue input buffer inputIndex = %d", __FUNCTION__, inputIndex);
+    CSFLogError(LOGTAG,  "%s queue input buffer inputIndex = %d", __FUNCTION__, inputIndex);
 #endif
 
     mMediaCodecEncoder->QueueInputBuffer(inputIndex, 0, size, inputImage.render_time_ms() * PR_USEC_PER_MSEC /* ms to us */, 0);
 #ifdef WEBRTC_MEDIACODEC_DEBUG
-    CSFLogDebug(logTag,  "%s WebrtcMediaCodecVP8VideoEncoder::Encode() queue input buffer took %u ms", __FUNCTION__, PR_IntervalToMilliseconds(PR_IntervalNow()-time));
+    CSFLogDebug(LOGTAG,  "%s WebrtcMediaCodecVP8VideoEncoder::Encode() queue input buffer took %u ms", __FUNCTION__, PR_IntervalToMilliseconds(PR_IntervalNow()-time));
 #endif
     mEncodedImage._encodedWidth = inputImage.width();
     mEncodedImage._encodedHeight = inputImage.height();
     mEncodedImage._timeStamp = inputImage.timestamp();
     mEncodedImage.capture_time_ms_ = inputImage.timestamp();
 
     nsresult res;
     BufferInfo::LocalRef bufferInfo;
     res = BufferInfo::New(&bufferInfo);
     if (NS_FAILED(res)) {
-      CSFLogDebug(logTag, "WebrtcMediaCodecVP8VideoEncoder::%s, BufferInfo::New return err = %d",
+      CSFLogDebug(LOGTAG, "WebrtcMediaCodecVP8VideoEncoder::%s, BufferInfo::New return err = %d",
                   __FUNCTION__, (int)res);
       return -1;
     }
 
     int32_t outputIndex = mMediaCodecEncoder->DequeueOutputBuffer(bufferInfo);
 
     if (outputIndex == MediaCodec::INFO_TRY_AGAIN_LATER) {
       // Not an error: output not available yet. Try later.
-      CSFLogDebug(logTag,  "%s dequeue output buffer try again:%d", __FUNCTION__, outputIndex);
+      CSFLogDebug(LOGTAG,  "%s dequeue output buffer try again:%d", __FUNCTION__, outputIndex);
     } else if (outputIndex == MediaCodec::INFO_OUTPUT_FORMAT_CHANGED) {
       // handle format change
-      CSFLogDebug(logTag,  "%s dequeue output buffer format changed:%d", __FUNCTION__, outputIndex);
+      CSFLogDebug(LOGTAG,  "%s dequeue output buffer format changed:%d", __FUNCTION__, outputIndex);
     } else if (outputIndex == MediaCodec::INFO_OUTPUT_BUFFERS_CHANGED) {
-      CSFLogDebug(logTag,  "%s dequeue output buffer changed:%d", __FUNCTION__, outputIndex);
+      CSFLogDebug(LOGTAG,  "%s dequeue output buffer changed:%d", __FUNCTION__, outputIndex);
       mMediaCodecEncoder->GetOutputBuffers();
     } else if (outputIndex < 0) {
-      CSFLogDebug(logTag,  "%s dequeue output buffer unknow error:%d", __FUNCTION__, outputIndex);
+      CSFLogDebug(LOGTAG,  "%s dequeue output buffer unknow error:%d", __FUNCTION__, outputIndex);
     } else {
 #ifdef WEBRTC_MEDIACODEC_DEBUG
-      CSFLogDebug(logTag,  "%s dequeue output buffer return status is %d took %u ms", __FUNCTION__, outputIndex, PR_IntervalToMilliseconds(PR_IntervalNow()-time));
+      CSFLogDebug(LOGTAG,  "%s dequeue output buffer return status is %d took %u ms", __FUNCTION__, outputIndex, PR_IntervalToMilliseconds(PR_IntervalNow()-time));
 #endif
 
       JNIEnv* env = jsjni_GetJNIForThread();
       jobject buffer = env->GetObjectArrayElement(mOutputBuffers, outputIndex);
       if (buffer) {
         int32_t offset;
         bufferInfo->Offset(&offset);
         int32_t flags;
@@ -893,21 +897,21 @@ int32_t WebrtcMediaCodecVP8VideoEncoder:
         } else {
           mEncodedImage._frameType = webrtc::kVideoFrameDelta;
         }
         mEncodedImage._completeFrame = true;
 
         int32_t size;
         bufferInfo->Size(&size);
 #ifdef WEBRTC_MEDIACODEC_DEBUG
-        CSFLogDebug(logTag,  "%s dequeue output buffer ok, index:%d, buffer size = %d, buffer offset = %d, flags = %d", __FUNCTION__, outputIndex, size, offset, flags);
+        CSFLogDebug(LOGTAG,  "%s dequeue output buffer ok, index:%d, buffer size = %d, buffer offset = %d, flags = %d", __FUNCTION__, outputIndex, size, offset, flags);
 #endif
 
         if(VerifyAndAllocate(size) == -1) {
-          CSFLogDebug(logTag,  "%s VerifyAndAllocate buffers failed", __FUNCTION__);
+          CSFLogDebug(LOGTAG,  "%s VerifyAndAllocate buffers failed", __FUNCTION__);
           return WEBRTC_VIDEO_CODEC_ERROR;
         }
 
         mEncodedImage._length = size;
 
         // xxx It's too bad the mediacodec API forces us to memcpy this....
         // we should find a way that able to 'hold' the buffer or transfer it from inputImage (ping-pong
         // buffers or select them from a small pool)
@@ -933,85 +937,85 @@ int32_t WebrtcMediaCodecVP8VideoEncoder:
       }
     }
   }
 
   return WEBRTC_VIDEO_CODEC_OK;
 }
 
 int32_t WebrtcMediaCodecVP8VideoEncoder::RegisterEncodeCompleteCallback(webrtc::EncodedImageCallback* callback) {
-  CSFLogDebug(logTag, "%s ", __FUNCTION__);
+  CSFLogDebug(LOGTAG, "%s ", __FUNCTION__);
   mCallback = callback;
 
   return WEBRTC_VIDEO_CODEC_OK;
 }
 
 int32_t WebrtcMediaCodecVP8VideoEncoder::Release() {
 
-  CSFLogDebug(logTag, "%s ", __FUNCTION__);
+  CSFLogDebug(LOGTAG, "%s ", __FUNCTION__);
   delete mMediaCodecEncoder;
   mMediaCodecEncoder = nullptr;
 
   delete [] mEncodedImage._buffer;
   mEncodedImage._buffer = nullptr;
   mEncodedImage._size = 0;
 
   return WEBRTC_VIDEO_CODEC_OK;
 }
 
 WebrtcMediaCodecVP8VideoEncoder::~WebrtcMediaCodecVP8VideoEncoder() {
-  CSFLogDebug(logTag,  "%s ", __FUNCTION__);
+  CSFLogDebug(LOGTAG,  "%s ", __FUNCTION__);
   Release();
 }
 
 int32_t WebrtcMediaCodecVP8VideoEncoder::SetChannelParameters(uint32_t packetLoss, int64_t rtt) {
-  CSFLogDebug(logTag,  "%s ", __FUNCTION__);
+  CSFLogDebug(LOGTAG,  "%s ", __FUNCTION__);
   return WEBRTC_VIDEO_CODEC_OK;
 }
 
 int32_t WebrtcMediaCodecVP8VideoEncoder::SetRates(uint32_t newBitRate, uint32_t frameRate) {
-  CSFLogDebug(logTag,  "%s ", __FUNCTION__);
+  CSFLogDebug(LOGTAG,  "%s ", __FUNCTION__);
   if (!mMediaCodecEncoder) {
     return WEBRTC_VIDEO_CODEC_UNINITIALIZED;
   }
 
   // XXX
   // 1. implement MediaCodec's setParameters method
   // 2.find a way to initiate a Java Bundle instance as parameter for MediaCodec setParameters method.
   // mMediaCodecEncoder->setParameters
 
   return WEBRTC_VIDEO_CODEC_OK;
 }
 
 WebrtcMediaCodecVP8VideoRemoteEncoder::~WebrtcMediaCodecVP8VideoRemoteEncoder() {
-  CSFLogDebug(logTag,  "%s %p", __FUNCTION__, this);
+  CSFLogDebug(LOGTAG,  "%s %p", __FUNCTION__, this);
   Release();
 }
 
 int32_t WebrtcMediaCodecVP8VideoRemoteEncoder::InitEncode(
     const webrtc::VideoCodec* codecSettings,
     int32_t numberOfCores,
     size_t maxPayloadSize) {
   return WEBRTC_VIDEO_CODEC_OK;
 }
 
 int32_t WebrtcMediaCodecVP8VideoRemoteEncoder::SetRates(uint32_t newBitRate, uint32_t frameRate) {
-  CSFLogDebug(logTag,  "%s, newBitRate: %d, frameRate: %d", __FUNCTION__, newBitRate, frameRate);
+  CSFLogDebug(LOGTAG,  "%s, newBitRate: %d, frameRate: %d", __FUNCTION__, newBitRate, frameRate);
   if (!mJavaEncoder) {
     return WEBRTC_VIDEO_CODEC_UNINITIALIZED;
   }
   mJavaEncoder->SetRates(newBitRate);
   return WEBRTC_VIDEO_CODEC_OK;
 }
 
 int32_t WebrtcMediaCodecVP8VideoRemoteEncoder::Encode(
     const webrtc::VideoFrame& inputImage,
     const webrtc::CodecSpecificInfo* codecSpecificInfo,
     const std::vector<webrtc::FrameType>* frame_types) {
-  CSFLogDebug(logTag,  "%s, w = %d, h = %d", __FUNCTION__, inputImage.width(), inputImage.height());
+  CSFLogDebug(LOGTAG,  "%s, w = %d, h = %d", __FUNCTION__, inputImage.width(), inputImage.height());
   if (inputImage.width() == 0 || inputImage.height() == 0) {
     return WEBRTC_VIDEO_CODEC_ERROR;
   }
 
   if (!mJavaEncoder) {
     JavaCallbacksSupport::Init();
     mJavaCallbacks = CodecProxy::NativeCallbacks::New();
 
@@ -1021,17 +1025,17 @@ int32_t WebrtcMediaCodecVP8VideoRemoteEn
     MediaFormat::LocalRef format;
 
     nsresult res = MediaFormat::CreateVideoFormat(nsCString(MEDIACODEC_VIDEO_MIME_VP8),
                                                   inputImage.width(),
                                                   inputImage.height(),
                                                   &format);
 
     if (NS_FAILED(res)) {
-      CSFLogDebug(logTag, "%s, CreateVideoFormat failed err = %d", __FUNCTION__, (int)res);
+      CSFLogDebug(LOGTAG, "%s, CreateVideoFormat failed err = %d", __FUNCTION__, (int)res);
       return WEBRTC_VIDEO_CODEC_ERROR;
     }
 
     res = format->SetInteger(nsCString("bitrate"), 300 * 1000);
     res = format->SetInteger(nsCString("bitrate-mode"), 2);
     res = format->SetInteger(nsCString("color-format"), 21);
     res = format->SetInteger(nsCString("frame-rate"), 30);
     res = format->SetInteger(nsCString("i-frame-interval"), 100);
@@ -1057,17 +1061,17 @@ int32_t WebrtcMediaCodecVP8VideoRemoteEn
     mConvertBufsize = size;
   }
 
   uint8_t* dstY = mConvertBuf;
   uint16_t* dstUV = reinterpret_cast<uint16_t*>(dstY + sizeY);
 
   bool converted = I420toNV12(dstY, dstUV, inputImage);
   if (!converted) {
-    CSFLogError(logTag,  "%s WebrtcMediaCodecVP8VideoEncoder::Encode() convert input buffer to NV12 error.", __FUNCTION__);
+    CSFLogError(LOGTAG,  "%s WebrtcMediaCodecVP8VideoEncoder::Encode() convert input buffer to NV12 error.", __FUNCTION__);
     return WEBRTC_VIDEO_CODEC_ERROR;
   }
 
   jni::ByteBuffer::LocalRef bytes = jni::ByteBuffer::New(mConvertBuf, size);
 
   BufferInfo::LocalRef bufferInfo;
   nsresult rv = BufferInfo::New(&bufferInfo);
   if (NS_FAILED(rv)) {
@@ -1086,17 +1090,17 @@ int32_t WebrtcMediaCodecVP8VideoRemoteEn
 }
 
 int32_t WebrtcMediaCodecVP8VideoRemoteEncoder::RegisterEncodeCompleteCallback(webrtc::EncodedImageCallback* callback) {
   mCallback = callback;
   return WEBRTC_VIDEO_CODEC_OK;
 }
 
 int32_t WebrtcMediaCodecVP8VideoRemoteEncoder::Release() {
-  CSFLogDebug(logTag,  "%s %p", __FUNCTION__, this);
+  CSFLogDebug(LOGTAG,  "%s %p", __FUNCTION__, this);
 
   if (mJavaEncoder) {
     mJavaEncoder->Release();
     mJavaEncoder = nullptr;
   }
 
   if (mJavaCallbacks) {
     JavaCallbacksSupport::GetNative(mJavaCallbacks)->Cancel();
@@ -1113,17 +1117,17 @@ int32_t WebrtcMediaCodecVP8VideoRemoteEn
 }
 
 // Decoder.
 WebrtcMediaCodecVP8VideoDecoder::WebrtcMediaCodecVP8VideoDecoder()
   : mCallback(nullptr)
   , mFrameWidth(0)
   , mFrameHeight(0)
   , mMediaCodecDecoder(nullptr) {
-  CSFLogDebug(logTag,  "%s ", __FUNCTION__);
+  CSFLogDebug(LOGTAG,  "%s ", __FUNCTION__);
 }
 
 bool WebrtcMediaCodecVP8VideoDecoder::ResetInputBuffers() {
   mInputBuffers = mMediaCodecDecoder->GetInputBuffers();
 
   if (!mInputBuffers)
     return false;
 
@@ -1153,102 +1157,102 @@ int32_t WebrtcMediaCodecVP8VideoDecoder:
 
 int32_t WebrtcMediaCodecVP8VideoDecoder::Decode(
     const webrtc::EncodedImage& inputImage,
     bool missingFrames,
     const webrtc::RTPFragmentationHeader* fragmentation,
     const webrtc::CodecSpecificInfo* codecSpecificInfo,
     int64_t renderTimeMs) {
 
-  CSFLogDebug(logTag,  "%s, renderTimeMs = %" PRId64, __FUNCTION__, renderTimeMs);
+  CSFLogDebug(LOGTAG,  "%s, renderTimeMs = %" PRId64, __FUNCTION__, renderTimeMs);
 
   if (inputImage._length== 0 || !inputImage._buffer) {
-    CSFLogDebug(logTag,  "%s, input Image invalid. length = %" PRIdPTR, __FUNCTION__, inputImage._length);
+    CSFLogDebug(LOGTAG,  "%s, input Image invalid. length = %" PRIdPTR, __FUNCTION__, inputImage._length);
     return WEBRTC_VIDEO_CODEC_ERROR;
   }
 
   if (inputImage._frameType == webrtc::kVideoFrameKey) {
-    CSFLogDebug(logTag,  "%s, inputImage is Golden frame",
+    CSFLogDebug(LOGTAG,  "%s, inputImage is Golden frame",
                   __FUNCTION__);
     mFrameWidth = inputImage._encodedWidth;
     mFrameHeight = inputImage._encodedHeight;
   }
 
   if (!mMediaCodecDecoder->isStarted) {
     if (mFrameWidth == 0 || mFrameHeight == 0) {
       return WEBRTC_VIDEO_CODEC_ERROR;
     }
 
     mMediaCodecDecoder->SetDecoderCallback(mCallback);
     nsresult res = mMediaCodecDecoder->Configure(mFrameWidth, mFrameHeight, nullptr, 0, MEDIACODEC_VIDEO_MIME_VP8, false /* decoder */);
 
     if (res != NS_OK) {
-      CSFLogDebug(logTag,  "%s, decoder configure return err = %d",
+      CSFLogDebug(LOGTAG,  "%s, decoder configure return err = %d",
                   __FUNCTION__, (int)res);
       return WEBRTC_VIDEO_CODEC_ERROR;
     }
 
     res = mMediaCodecDecoder->Start();
 
     if (NS_FAILED(res)) {
       mMediaCodecDecoder->isStarted = false;
-      CSFLogDebug(logTag,  "%s start decoder. err = %d", __FUNCTION__, (int)res);
+      CSFLogDebug(LOGTAG,  "%s start decoder. err = %d", __FUNCTION__, (int)res);
       return WEBRTC_VIDEO_CODEC_ERROR;
     }
 
     bool retBool = ResetInputBuffers();
     if (!retBool) {
-      CSFLogDebug(logTag,  "%s ResetInputBuffers failed.", __FUNCTION__);
+      CSFLogDebug(LOGTAG,  "%s ResetInputBuffers failed.", __FUNCTION__);
       return WEBRTC_VIDEO_CODEC_ERROR;
     }
     retBool = ResetOutputBuffers();
     if (!retBool) {
-      CSFLogDebug(logTag,  "%s ResetOutputBuffers failed.", __FUNCTION__);
+      CSFLogDebug(LOGTAG,  "%s ResetOutputBuffers failed.", __FUNCTION__);
       return WEBRTC_VIDEO_CODEC_ERROR;
     }
 
     mMediaCodecDecoder->isStarted = true;
   }
 #ifdef WEBRTC_MEDIACODEC_DEBUG
   uint32_t time = PR_IntervalNow();
-  CSFLogDebug(logTag,  "%s start decoder took %u ms", __FUNCTION__, PR_IntervalToMilliseconds(PR_IntervalNow()-time));
+  CSFLogDebug(LOGTAG,  "%s start decoder took %u ms", __FUNCTION__, PR_IntervalToMilliseconds(PR_IntervalNow()-time));
 #endif
 
   bool feedFrame = true;
   int32_t ret = WEBRTC_VIDEO_CODEC_ERROR;
 
   while (feedFrame) {
     ret = mMediaCodecDecoder->FeedMediaCodecInput(inputImage, renderTimeMs);
     feedFrame = (ret == -1);
   }
 
-  CSFLogDebug(logTag,  "%s end, ret = %d", __FUNCTION__, ret);
+  CSFLogDebug(LOGTAG,  "%s end, ret = %d", __FUNCTION__, ret);
 
   return ret;
 }
 
 void WebrtcMediaCodecVP8VideoDecoder::DecodeFrame(EncodedFrame* frame) {
-  CSFLogDebug(logTag,  "%s ", __FUNCTION__);
+  CSFLogDebug(LOGTAG,  "%s ", __FUNCTION__);
 }
 
 int32_t WebrtcMediaCodecVP8VideoDecoder::RegisterDecodeCompleteCallback(webrtc::DecodedImageCallback* callback) {
-  CSFLogDebug(logTag,  "%s ", __FUNCTION__);
+  CSFLogDebug(LOGTAG,  "%s ", __FUNCTION__);
 
   mCallback = callback;
   return WEBRTC_VIDEO_CODEC_OK;
 }
 
 int32_t WebrtcMediaCodecVP8VideoDecoder::Release() {
-  CSFLogDebug(logTag,  "%s ", __FUNCTION__);
+  CSFLogDebug(LOGTAG,  "%s ", __FUNCTION__);
 
   delete mMediaCodecDecoder;
   mMediaCodecDecoder = nullptr;
 
   return WEBRTC_VIDEO_CODEC_OK;
 }
 
 WebrtcMediaCodecVP8VideoDecoder::~WebrtcMediaCodecVP8VideoDecoder() {
-  CSFLogDebug(logTag,  "%s ", __FUNCTION__);
+  CSFLogDebug(LOGTAG,  "%s ", __FUNCTION__);
 
   Release();
 }
 
 }
--- a/media/webrtc/signaling/src/media-conduit/moz.build
+++ b/media/webrtc/signaling/src/media-conduit/moz.build
@@ -13,28 +13,24 @@ LOCAL_INCLUDES += [
     '/media/webrtc',
     '/media/webrtc/signaling/src/common',
     '/media/webrtc/signaling/src/common/browser_logging',
     '/media/webrtc/signaling/src/common/time_profiling',
     '/media/webrtc/signaling/src/peerconnection',
     '/media/webrtc/trunk',
 ]
 
-SOURCES += [
+UNIFIED_SOURCES += [
     'AudioConduit.cpp',
-    'VideoConduit.cpp',
-]
-
-UNIFIED_SOURCES += [
     'GmpVideoCodec.cpp',
     'MediaDataDecoderCodec.cpp',
+    'VideoConduit.cpp',
     'WebrtcGmpVideoCodec.cpp',
     'WebrtcMediaDataDecoderCodec.cpp',
 ]
 
 if CONFIG['OS_TARGET'] == 'Android':
-    # Duplicate definition of logTag
-    SOURCES += [
+    UNIFIED_SOURCES += [
         'MediaCodecVideoCodec.cpp',
         'WebrtcMediaCodecVP8VideoCodec.cpp',
     ]
 
 FINAL_LIBRARY = 'xul'
--- a/media/webrtc/signaling/src/mediapipeline/MediaPipeline.cpp
+++ b/media/webrtc/signaling/src/mediapipeline/MediaPipeline.cpp
@@ -4,16 +4,17 @@
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 // Original author: ekr@rtfm.com
 
 #include "MediaPipeline.h"
 
 #include "MediaStreamGraphImpl.h"
 
+#include <inttypes.h>
 #include <math.h>
 
 #include "nspr.h"
 #include "srtp.h"
 
 #include "VideoSegment.h"
 #include "Layers.h"
 #include "LayersLogging.h"
@@ -51,32 +52,35 @@
 
 #include "webrtc/common_types.h"
 #include "webrtc/common_video/libyuv/include/webrtc_libyuv.h"
 #include "webrtc/common_video/include/video_frame_buffer.h"
 #include "webrtc/base/bind.h"
 
 #include "nsThreadUtils.h"
 
-#include "logging.h"
+#include "CSFLog.h"
 
 // Max size given stereo is 480*2*2 = 1920 (10ms of 16-bits stereo audio at
 // 48KHz)
 #define AUDIO_SAMPLE_BUFFER_MAX_BYTES 480*2*2
 static_assert((WEBRTC_DEFAULT_SAMPLE_RATE/100)*sizeof(uint16_t) * 2
                <= AUDIO_SAMPLE_BUFFER_MAX_BYTES,
                "AUDIO_SAMPLE_BUFFER_MAX_BYTES is not large enough");
 
 using namespace mozilla;
 using namespace mozilla::dom;
 using namespace mozilla::gfx;
 using namespace mozilla::layers;
 
-// Logging context
-MOZ_MTLOG_MODULE("mediapipeline")
+static const char* mpLogTag = "MediaPipeline";
+#ifdef LOGTAG
+#undef LOGTAG
+#endif
+#define LOGTAG mpLogTag
 
 namespace mozilla {
 extern mozilla::LogModule* AudioLogModule();
 
 class VideoConverterListener
 {
 public:
   NS_INLINE_DECL_THREADSAFE_REFCOUNTING(VideoConverterListener)
@@ -143,36 +147,35 @@ public:
     }
     last_img_ = serial;
 
     // A throttling limit of 1 allows us to convert 2 frames concurrently.
     // It's short enough to not build up too significant a delay, while
     // giving us a margin to not cause some machines to drop every other frame.
     const int32_t queueThrottlingLimit = 1;
     if (mLength > queueThrottlingLimit) {
-      MOZ_MTLOG(ML_DEBUG, "VideoFrameConverter " << this << " queue is full." <<
-                          " Throttling by throwing away a frame.");
+      CSFLogDebug(LOGTAG, "VideoFrameConverter %p queue is full. Throttling by throwing away a frame.",
+                  this);
 #ifdef DEBUG
       ++mThrottleCount;
       mThrottleRecord = std::max(mThrottleCount, mThrottleRecord);
 #endif
       return;
     }
 
 #ifdef DEBUG
     if (mThrottleCount > 0) {
-      auto level = ML_DEBUG;
       if (mThrottleCount > 5) {
         // Log at a higher level when we have large drops.
-        level = ML_INFO;
+        CSFLogInfo(LOGTAG, "VideoFrameConverter %p stopped throttling after throwing away %d frames. Longest throttle so far was %d frames.",
+                   this, mThrottleCount, mThrottleRecord);
+      } else {
+        CSFLogDebug(LOGTAG, "VideoFrameConverter %p stopped throttling after throwing away %d frames. Longest throttle so far was %d frames.",
+                    this, mThrottleCount, mThrottleRecord);
       }
-      MOZ_MTLOG(level, "VideoFrameConverter " << this << " stopped" <<
-                       " throttling after throwing away " << mThrottleCount <<
-                       " frames. Longest throttle so far was " <<
-                       mThrottleRecord << " frames.");
       mThrottleCount = 0;
     }
 #endif
 
     bool forceBlack = aForceBlack || aChunk.mFrame.GetForceBlack();
 
     if (forceBlack) {
       // Reset the last-img check.
@@ -245,17 +248,17 @@ protected:
                            unsigned int aVideoFrameLength,
                            unsigned short aWidth,
                            unsigned short aHeight,
                            VideoType aVideoType,
                            uint64_t aCaptureTime)
   {
     // check for parameter sanity
     if (!aBuffer || aVideoFrameLength == 0 || aWidth == 0 || aHeight == 0) {
-      MOZ_MTLOG(ML_ERROR, __FUNCTION__ << " Invalid Parameters ");
+      CSFLogError(LOGTAG, "%s Invalid Parameters", __FUNCTION__);
       MOZ_ASSERT(false);
       return;
     }
     MOZ_ASSERT(aVideoType == VideoType::kVideoI420);
 
     const int stride_y = aWidth;
     const int stride_uv = (aWidth + 1) / 2;
 
@@ -303,17 +306,17 @@ protected:
       // Send a black image.
       auto pixelData = MakeUniqueFallible<uint8_t[]>(length.value());
       if (pixelData) {
         // YCrCb black = 0x10 0x80 0x80
         memset(pixelData.get(), 0x10, yPlaneLen.value());
         // Fill Cb/Cr planes
         memset(pixelData.get() + yPlaneLen.value(), 0x80, cbcrPlaneLen);
 
-        MOZ_MTLOG(ML_DEBUG, "Sending a black video frame");
+        CSFLogDebug(LOGTAG, "Sending a black video frame");
         VideoFrameConverted(Move(pixelData), length.value(),
                             size.width, size.height,
                             mozilla::kVideoI420, 0);
       }
       return;
     }
 
     ImageFormat format = aImage->GetFormat();
@@ -339,33 +342,34 @@ protected:
             y, yStride,
             cb, cbCrStride,
             cr, cbCrStride,
             callback_unused));
 
         webrtc::VideoFrame i420_frame(video_frame_buffer,
                                       0, 0, // not setting timestamps
                                       webrtc::kVideoRotation_0);
-        MOZ_MTLOG(ML_DEBUG, "Sending an I420 video frame");
+        CSFLogDebug(LOGTAG, "Sending an I420 video frame");
         VideoFrameConverted(i420_frame);
         return;
       }
     }
 
     RefPtr<SourceSurface> surf = aImage->GetAsSourceSurface();
     if (!surf) {
-      MOZ_MTLOG(ML_ERROR, "Getting surface from " << Stringify(format) << " image failed");
+      CSFLogError(LOGTAG, "Getting surface from %s image failed",
+                  Stringify(format).c_str());
       return;
     }
 
     RefPtr<DataSourceSurface> data = surf->GetDataSurface();
     if (!data) {
-      MOZ_MTLOG(ML_ERROR, "Getting data surface from " << Stringify(format)
-                          << " image with " << Stringify(surf->GetType()) << "("
-                          << Stringify(surf->GetFormat()) << ") surface failed");
+      CSFLogError(LOGTAG, "Getting data surface from %s image with %s (%s) surface failed",
+                  Stringify(format).c_str(), Stringify(surf->GetType()).c_str(),
+                  Stringify(surf->GetFormat()).c_str());
       return;
     }
 
     IntSize size = aImage->GetSize();
     // these don't need to be CheckedInt, any overflow will be caught by YSIZE
     int half_width = (size.width + 1) >> 1;
     int half_height = (size.height + 1) >> 1;
     int c_size = half_width * half_height;
@@ -378,19 +382,19 @@ protected:
     auto yuv_scoped = MakeUniqueFallible<uint8[]>(buffer_size.value());
     if (!yuv_scoped) {
       return;
     }
     uint8* yuv = yuv_scoped.get();
 
     DataSourceSurface::ScopedMap map(data, DataSourceSurface::READ);
     if (!map.IsMapped()) {
-      MOZ_MTLOG(ML_ERROR, "Reading DataSourceSurface from " << Stringify(format)
-                          << " image with " << Stringify(surf->GetType()) << "("
-                          << Stringify(surf->GetFormat()) << ") surface failed");
+      CSFLogError(LOGTAG, "Reading DataSourceSurface from %s image with %s (%s) surface failed",
+                  Stringify(format).c_str(), Stringify(surf->GetType()).c_str(),
+                  Stringify(surf->GetFormat()).c_str());
       return;
     }
 
     int rv;
     int cb_offset = YSIZE(size.width, size.height).value();
     int cr_offset = cb_offset + c_size;
     switch (surf->GetFormat()) {
       case SurfaceFormat::B8G8R8A8:
@@ -406,26 +410,28 @@ protected:
         rv = libyuv::RGB565ToI420(static_cast<uint8*>(map.GetData()),
                                   map.GetStride(),
                                   yuv, size.width,
                                   yuv + cb_offset, half_width,
                                   yuv + cr_offset, half_width,
                                   size.width, size.height);
         break;
       default:
-        MOZ_MTLOG(ML_ERROR, "Unsupported RGB video format" << Stringify(surf->GetFormat()));
+        CSFLogError(LOGTAG, "Unsupported RGB video format %s",
+                    Stringify(surf->GetFormat()).c_str());
         MOZ_ASSERT(PR_FALSE);
         return;
     }
     if (rv != 0) {
-      MOZ_MTLOG(ML_ERROR, Stringify(surf->GetFormat()) << " to I420 conversion failed");
+      CSFLogError(LOGTAG, "%s to I420 conversion failed",
+                  Stringify(surf->GetFormat()).c_str());
       return;
     }
-    MOZ_MTLOG(ML_DEBUG, "Sending an I420 video frame converted from " <<
-                        Stringify(surf->GetFormat()));
+    CSFLogDebug(LOGTAG, "Sending an I420 video frame converted from %s",
+                Stringify(surf->GetFormat()).c_str());
     VideoFrameConverted(Move(yuv_scoped), buffer_size.value(), size.width, size.height, mozilla::kVideoI420, 0);
   }
 
   Atomic<int32_t, Relaxed> mLength;
   RefPtr<TaskQueue> mTaskQueue;
 
   // Written and read from the queueing thread (normally MSG).
   int32_t last_img_; // serial number of last Image
@@ -589,17 +595,17 @@ MediaPipeline::MediaPipeline(const std::
   MOZ_ASSERT(rtp_transport != rtcp_transport);
 
   // PipelineTransport() will access this->sts_thread_; moved here for safety
   transport_ = new PipelineTransport(this);
 }
 
 MediaPipeline::~MediaPipeline() {
   ASSERT_ON_THREAD(main_thread_);
-  MOZ_MTLOG(ML_INFO, "Destroying MediaPipeline: " << description_);
+  CSFLogInfo(LOGTAG, "Destroying MediaPipeline: %s", description_.c_str());
 }
 
 nsresult MediaPipeline::Init() {
   ASSERT_ON_THREAD(main_thread_);
   packet_dumper_ = new PacketDumper(pc_);
 
   if (direction_ == RECEIVE) {
     conduit_->SetReceiverTransport(transport_);
@@ -765,17 +771,17 @@ MediaPipeline::GetContributingSourceStat
   }
 }
 
 void MediaPipeline::StateChange(TransportFlow *flow, TransportLayer::State state) {
   TransportInfo* info = GetTransportInfo_s(flow);
   MOZ_ASSERT(info);
 
   if (state == TransportLayer::TS_OPEN) {
-    MOZ_MTLOG(ML_INFO, "Flow is ready");
+    CSFLogInfo(LOGTAG, "Flow is ready");
     TransportReady_s(*info);
   } else if (state == TransportLayer::TS_CLOSED ||
              state == TransportLayer::TS_ERROR) {
     TransportFailed_s(*info);
   }
 }
 
 static bool MakeRtpTypeToStringArray(const char** array) {
@@ -797,48 +803,47 @@ static const char* ToString(MediaPipelin
 }
 
 nsresult MediaPipeline::TransportReady_s(TransportInfo &info) {
   MOZ_ASSERT(!description_.empty());
 
   // TODO(ekr@rtfm.com): implement some kind of notification on
   // failure. bug 852665.
   if (info.state_ != MP_CONNECTING) {
-    MOZ_MTLOG(ML_ERROR, "Transport ready for flow in wrong state:" <<
-              description_ << ": " << ToString(info.type_));
+    CSFLogError(LOGTAG, "Transport ready for flow in wrong state:%s :%s",
+                description_.c_str(), ToString(info.type_));
     return NS_ERROR_FAILURE;
   }
 
-  MOZ_MTLOG(ML_INFO, "Transport ready for pipeline " <<
-            static_cast<void *>(this) << " flow " << description_ << ": " <<
-            ToString(info.type_));
+  CSFLogInfo(LOGTAG, "Transport ready for pipeline %p flow %s: %s", this,
+             description_.c_str(), ToString(info.type_));
 
   // TODO(bcampen@mozilla.com): Should we disconnect from the flow on failure?
   nsresult res;
 
   // Now instantiate the SRTP objects
   TransportLayerDtls *dtls = static_cast<TransportLayerDtls *>(
       info.transport_->GetLayer(TransportLayerDtls::ID()));
   MOZ_ASSERT(dtls);  // DTLS is mandatory
 
   uint16_t cipher_suite;
   res = dtls->GetSrtpCipher(&cipher_suite);
   if (NS_FAILED(res)) {
-    MOZ_MTLOG(ML_ERROR, "Failed to negotiate DTLS-SRTP. This is an error");
+    CSFLogError(LOGTAG, "Failed to negotiate DTLS-SRTP. This is an error");
     info.state_ = MP_CLOSED;
     UpdateRtcpMuxState(info);
     return res;
   }
 
   // SRTP Key Exporter as per RFC 5764 S 4.2
   unsigned char srtp_block[SRTP_TOTAL_KEY_LENGTH * 2];
   res = dtls->ExportKeyingMaterial(kDTLSExporterLabel, false, "",
                                    srtp_block, sizeof(srtp_block));
   if (NS_FAILED(res)) {
-    MOZ_MTLOG(ML_ERROR, "Failed to compute DTLS-SRTP keys. This is an error");
+    CSFLogError(LOGTAG, "Failed to compute DTLS-SRTP keys. This is an error");
     info.state_ = MP_CLOSED;
     UpdateRtcpMuxState(info);
     MOZ_CRASH();  // TODO: Remove once we have enough field experience to
                   // know it doesn't happen. bug 798797. Note that the
                   // code after this never executes.
     return res;
   }
 
@@ -870,26 +875,25 @@ nsresult MediaPipeline::TransportReady_s
   }
 
   MOZ_ASSERT(!info.send_srtp_ && !info.recv_srtp_);
   info.send_srtp_ = SrtpFlow::Create(cipher_suite, false, write_key,
                                      SRTP_TOTAL_KEY_LENGTH);
   info.recv_srtp_ = SrtpFlow::Create(cipher_suite, true, read_key,
                                      SRTP_TOTAL_KEY_LENGTH);
   if (!info.send_srtp_ || !info.recv_srtp_) {
-    MOZ_MTLOG(ML_ERROR, "Couldn't create SRTP flow for "
-              << ToString(info.type_));
+    CSFLogError(LOGTAG, "Couldn't create SRTP flow for %s",
+                ToString(info.type_));
     info.state_ = MP_CLOSED;
     UpdateRtcpMuxState(info);
     return NS_ERROR_FAILURE;
   }
 
-    MOZ_MTLOG(ML_INFO, "Listening for " << ToString(info.type_)
-                       << " packets received on " <<
-                       static_cast<void *>(dtls->downward()));
+  CSFLogInfo(LOGTAG, "Listening for %s packets received on %p",
+             ToString(info.type_), dtls->downward());
 
   switch (info.type_) {
     case RTP:
       dtls->downward()->SignalPacketReceived.connect(
           this,
           &MediaPipeline::RtpPacketReceived);
       break;
     case RTCP:
@@ -912,17 +916,17 @@ nsresult MediaPipeline::TransportReady_s
 }
 
 nsresult MediaPipeline::TransportFailed_s(TransportInfo &info) {
   ASSERT_ON_THREAD(sts_thread_);
 
   info.state_ = MP_CLOSED;
   UpdateRtcpMuxState(info);
 
-  MOZ_MTLOG(ML_INFO, "Transport closed for flow " << ToString(info.type_));
+  CSFLogInfo(LOGTAG, "Transport closed for flow %s", ToString(info.type_));
 
   NS_WARNING(
       "MediaPipeline Transport failed. This is not properly cleaned up yet");
 
   // TODO(ekr@rtfm.com): SECURITY: Figure out how to clean up if the
   // connection was good and now it is bad.
   // TODO(ekr@rtfm.com): Report up so that the PC knows we
   // have experienced an error.
@@ -954,88 +958,82 @@ nsresult MediaPipeline::SendPacket(Trans
   TransportResult res = dtls->downward()->
       SendPacket(static_cast<const unsigned char *>(data), len);
 
   if (res != len) {
     // Ignore blocking indications
     if (res == TE_WOULDBLOCK)
       return NS_OK;
 
-    MOZ_MTLOG(ML_ERROR, "Failed write on stream " << description_);
+    CSFLogError(LOGTAG, "Failed write on stream %s", description_.c_str());
     return NS_BASE_STREAM_CLOSED;
   }
 
   return NS_OK;
 }
 
 void MediaPipeline::increment_rtp_packets_sent(int32_t bytes) {
   ++rtp_packets_sent_;
   rtp_bytes_sent_ += bytes;
 
   if (!(rtp_packets_sent_ % 100)) {
-    MOZ_MTLOG(ML_INFO, "RTP sent packet count for " << description_
-              << " Pipeline " << static_cast<void *>(this)
-              << " Flow : " << static_cast<void *>(rtp_.transport_)
-              << ": " << rtp_packets_sent_
-              << " (" << rtp_bytes_sent_ << " bytes)");
+    CSFLogInfo(LOGTAG, "RTP sent packet count for %s Pipeline %p Flow: %p: %u (%" PRId64 " bytes)",
+               description_.c_str(), this, static_cast<void *>(rtp_.transport_),
+               rtp_packets_sent_, rtp_bytes_sent_);
   }
 }
 
 void MediaPipeline::increment_rtcp_packets_sent() {
   ++rtcp_packets_sent_;
   if (!(rtcp_packets_sent_ % 100)) {
-    MOZ_MTLOG(ML_INFO, "RTCP sent packet count for " << description_
-              << " Pipeline " << static_cast<void *>(this)
-              << " Flow : " << static_cast<void *>(rtcp_.transport_)
-              << ": " << rtcp_packets_sent_);
+    CSFLogInfo(LOGTAG, "RTCP sent packet count for %s Pipeline %p Flow: %p: %u",
+               description_.c_str(), this, static_cast<void *>(rtp_.transport_),
+               rtcp_packets_sent_);
   }
 }
 
 void MediaPipeline::increment_rtp_packets_received(int32_t bytes) {
   ++rtp_packets_received_;
   rtp_bytes_received_ += bytes;
   if (!(rtp_packets_received_ % 100)) {
-    MOZ_MTLOG(ML_INFO, "RTP received packet count for " << description_
-              << " Pipeline " << static_cast<void *>(this)
-              << " Flow : " << static_cast<void *>(rtp_.transport_)
-              << ": " << rtp_packets_received_
-              << " (" << rtp_bytes_received_ << " bytes)");
+    CSFLogInfo(LOGTAG, "RTP received packet count for %s Pipeline %p Flow: %p: %u (%" PRId64 " bytes)",
+               description_.c_str(), this, static_cast<void *>(rtp_.transport_),
+               rtp_packets_received_, rtp_bytes_received_);
   }
 }
 
 void MediaPipeline::increment_rtcp_packets_received() {
   ++rtcp_packets_received_;
   if (!(rtcp_packets_received_ % 100)) {
-    MOZ_MTLOG(ML_INFO, "RTCP received packet count for " << description_
-              << " Pipeline " << static_cast<void *>(this)
-              << " Flow : " << static_cast<void *>(rtcp_.transport_)
-              << ": " << rtcp_packets_received_);
+    CSFLogInfo(LOGTAG, "RTCP received packet count for %s Pipeline %p Flow: %p: %u",
+               description_.c_str(), this, static_cast<void *>(rtp_.transport_),
+               rtcp_packets_received_);
   }
 }
 
 void MediaPipeline::RtpPacketReceived(TransportLayer *layer,
                                       const unsigned char *data,
                                       size_t len) {
   if (!transport_->pipeline()) {
-    MOZ_MTLOG(ML_ERROR, "Discarding incoming packet; transport disconnected");
+    CSFLogError(LOGTAG, "Discarding incoming packet; transport disconnected");
     return;
   }
 
   if (!conduit_) {
-    MOZ_MTLOG(ML_DEBUG, "Discarding incoming packet; media disconnected");
+    CSFLogDebug(LOGTAG, "Discarding incoming packet; media disconnected");
     return;
   }
 
   if (rtp_.state_ != MP_OPEN) {
-    MOZ_MTLOG(ML_ERROR, "Discarding incoming packet; pipeline not open");
+    CSFLogError(LOGTAG, "Discarding incoming packet; pipeline not open");
     return;
   }
 
   if (rtp_.transport_->state() != TransportLayer::TS_OPEN) {
-    MOZ_MTLOG(ML_ERROR, "Discarding incoming packet; transport not open");
+    CSFLogError(LOGTAG, "Discarding incoming packet; transport not open");
     return;
   }
 
   // This should never happen.
   MOZ_ASSERT(rtp_.recv_srtp_);
 
   if (direction_ == TRANSMIT) {
     return;
@@ -1110,52 +1108,52 @@ void MediaPipeline::RtpPacketReceived(Tr
     char tmp[16];
 
     SprintfLiteral(tmp, "%.2x %.2x %.2x %.2x",
                    inner_data[0],
                    inner_data[1],
                    inner_data[2],
                    inner_data[3]);
 
-    MOZ_MTLOG(ML_NOTICE, "Error unprotecting RTP in " << description_
-              << "len= " << len << "[" << tmp << "...]");
+    CSFLogError(LOGTAG, "Error unprotecting RTP in %s len= %zu [%s]",
+                description_.c_str(), len, tmp);
     return;
   }
-  MOZ_MTLOG(ML_DEBUG, description_ << " received RTP packet.");
+  CSFLogDebug(LOGTAG, "%s received RTP packet.", description_.c_str());
   increment_rtp_packets_received(out_len);
 
   RtpLogger::LogPacket(inner_data.get(), out_len, true, true, header.headerLength,
                        description_);
 
   packet_dumper_->Dump(
       level_, dom::mozPacketDumpType::Rtp, false, inner_data.get(), out_len);
 
   (void)conduit_->ReceivedRTPPacket(inner_data.get(), out_len, header.ssrc);  // Ignore error codes
 }
 
 void MediaPipeline::RtcpPacketReceived(TransportLayer *layer,
                                        const unsigned char *data,
                                        size_t len) {
   if (!transport_->pipeline()) {
-    MOZ_MTLOG(ML_DEBUG, "Discarding incoming packet; transport disconnected");
+    CSFLogDebug(LOGTAG, "Discarding incoming packet; transport disconnected");
     return;
   }
 
   if (!conduit_) {
-    MOZ_MTLOG(ML_DEBUG, "Discarding incoming packet; media disconnected");
+    CSFLogDebug(LOGTAG, "Discarding incoming packet; media disconnected");
     return;
   }
 
   if (rtcp_.state_ != MP_OPEN) {
-    MOZ_MTLOG(ML_DEBUG, "Discarding incoming packet; pipeline not open");
+    CSFLogDebug(LOGTAG, "Discarding incoming packet; pipeline not open");
     return;
   }
 
   if (rtcp_.transport_->state() != TransportLayer::TS_OPEN) {
-    MOZ_MTLOG(ML_ERROR, "Discarding incoming packet; transport not open");
+    CSFLogError(LOGTAG, "Discarding incoming packet; transport not open");
     return;
   }
 
   if (!len) {
     return;
   }
 
   // Filter out everything but RTP/RTCP
@@ -1163,17 +1161,17 @@ void MediaPipeline::RtcpPacketReceived(T
     return;
   }
 
   // We do not filter RTCP for send pipelines, since the webrtc.org code for
   // senders already has logic to ignore RRs that do not apply.
   // TODO bug 1279153: remove SR check for reduced size RTCP
   if (filter_ && direction_ == RECEIVE) {
     if (!filter_->FilterSenderReport(data, len)) {
-      MOZ_MTLOG(ML_NOTICE, "Dropping incoming RTCP packet; filtered out");
+      CSFLogWarn(LOGTAG, "Dropping incoming RTCP packet; filtered out");
       return;
     }
   }
 
   packet_dumper_->Dump(
       level_, dom::mozPacketDumpType::Srtcp, false, data, len);
 
   // Make a copy rather than cast away constness
@@ -1184,17 +1182,17 @@ void MediaPipeline::RtcpPacketReceived(T
   nsresult res = rtcp_.recv_srtp_->UnprotectRtcp(inner_data.get(),
                                                  len,
                                                  len,
                                                  &out_len);
 
   if (!NS_SUCCEEDED(res))
     return;
 
-  MOZ_MTLOG(ML_DEBUG, description_ << " received RTCP packet.");
+  CSFLogDebug(LOGTAG, "%s received RTCP packet.", description_.c_str());
   increment_rtcp_packets_received();
 
   RtpLogger::LogPacket(inner_data.get(), out_len, true, false, 0, description_);
 
   packet_dumper_->Dump(
       level_, dom::mozPacketDumpType::Rtcp, false, data, len);
 
   MOZ_ASSERT(rtcp_.recv_srtp_);  // This should never happen
@@ -1234,17 +1232,17 @@ bool MediaPipeline::IsRtp(const unsigned
   MOZ_ASSERT(false);  // Not reached, belt and suspenders.
   return true;
 }
 
 void MediaPipeline::PacketReceived(TransportLayer *layer,
                                    const unsigned char *data,
                                    size_t len) {
   if (!transport_->pipeline()) {
-    MOZ_MTLOG(ML_DEBUG, "Discarding incoming packet; transport disconnected");
+    CSFLogDebug(LOGTAG, "Discarding incoming packet; transport disconnected");
     return;
   }
 
   if (IsRtp(data, len)) {
     RtpPacketReceived(layer, data, len);
   } else {
     RtcpPacketReceived(layer, data, len);
   }
@@ -1481,19 +1479,18 @@ void MediaPipelineTransmit::AttachToTrac
 
   description_ = pc_ + "| ";
   description_ += conduit_->type() == MediaSessionConduit::AUDIO ?
       "Transmit audio[" : "Transmit video[";
   description_ += track_id;
   description_ += "]";
 
   // TODO(ekr@rtfm.com): Check for errors
-  MOZ_MTLOG(ML_DEBUG, "Attaching pipeline to track "
-            << static_cast<void *>(domtrack_) << " conduit type=" <<
-            (conduit_->type() == MediaSessionConduit::AUDIO ?"audio":"video"));
+  CSFLogDebug(LOGTAG, "Attaching pipeline to track %p conduit type=%s", this,
+              (conduit_->type() == MediaSessionConduit::AUDIO ?"audio":"video"));
 
 #if !defined(MOZILLA_EXTERNAL_LINKAGE)
   // With full duplex we don't risk having audio come in late to the MSG
   // so we won't need a direct listener.
   const bool enableDirectListener =
     !Preferences::GetBool("media.navigator.audio.full_duplex", false);
 #else
   const bool enableDirectListener = true;
@@ -1579,20 +1576,19 @@ nsresult MediaPipelineTransmit::Transpor
   return NS_OK;
 }
 
 nsresult MediaPipelineTransmit::ReplaceTrack(MediaStreamTrack& domtrack) {
   // MainThread, checked in calls we make
   nsString nsTrackId;
   domtrack.GetId(nsTrackId);
   std::string track_id(NS_ConvertUTF16toUTF8(nsTrackId).get());
-  MOZ_MTLOG(ML_DEBUG, "Reattaching pipeline " << description_ << " to track "
-            << static_cast<void *>(&domtrack)
-            << " track " << track_id << " conduit type=" <<
-            (conduit_->type() == MediaSessionConduit::AUDIO ?"audio":"video"));
+  CSFLogDebug(LOGTAG, "Reattaching pipeline %s to track %p track %s conduit type: %s",
+              description_.c_str(), &domtrack, track_id.c_str(),
+              (conduit_->type() == MediaSessionConduit::AUDIO ?"audio":"video"));
 
   DetachMedia();
   domtrack_ = &domtrack; // Detach clears it
   // Unsets the track id after RemoveListener() takes effect.
   listener_->UnsetTrackId(domtrack_->GraphImpl());
   track_id_ = track_id;
   AttachToTrack(track_id);
   return NS_OK;
@@ -1615,23 +1611,23 @@ void MediaPipeline::DisconnectTransport_
 nsresult MediaPipeline::ConnectTransport_s(TransportInfo &info) {
   MOZ_ASSERT(info.transport_);
   ASSERT_ON_THREAD(sts_thread_);
 
   // Look to see if the transport is ready
   if (info.transport_->state() == TransportLayer::TS_OPEN) {
     nsresult res = TransportReady_s(info);
     if (NS_FAILED(res)) {
-      MOZ_MTLOG(ML_ERROR, "Error calling TransportReady(); res="
-                << static_cast<uint32_t>(res) << " in " << __FUNCTION__);
+      CSFLogError(LOGTAG, "Error calling TransportReady(); res=%u in %s",
+                  static_cast<uint32_t>(res), __FUNCTION__);
       return res;
     }
   } else if (info.transport_->state() == TransportLayer::TS_ERROR) {
-    MOZ_MTLOG(ML_ERROR, ToString(info.type_)
-                        << "transport is already in error state");
+    CSFLogError(LOGTAG, "%s transport is already in error state",
+                ToString(info.type_));
     TransportFailed_s(info);
     return NS_ERROR_FAILURE;
   }
 
   info.transport_->SignalStateChange.connect(this,
                                              &MediaPipeline::StateChange);
 
   return NS_OK;
@@ -1672,17 +1668,17 @@ nsresult MediaPipeline::PipelineTranspor
 
   ASSERT_ON_THREAD(sts_thread_);
   if (!pipeline_) {
     return NS_OK;  // Detached
   }
   TransportInfo& transport = is_rtp ? pipeline_->rtp_ : pipeline_->rtcp_;
 
   if (!transport.send_srtp_) {
-    MOZ_MTLOG(ML_DEBUG, "Couldn't write RTP/RTCP packet; SRTP not set up yet");
+    CSFLogDebug(LOGTAG, "Couldn't write RTP/RTCP packet; SRTP not set up yet");
     return NS_OK;
   }
 
   MOZ_ASSERT(transport.transport_);
   NS_ENSURE_TRUE(transport.transport_, NS_ERROR_NULL_POINTER);
 
   // libsrtp enciphers in place, so we need a big enough buffer.
   MOZ_ASSERT(data->capacity() >= data->len() + SRTP_MAX_EXPANSION);
@@ -1719,18 +1715,18 @@ nsresult MediaPipeline::PipelineTranspor
   }
   if (!NS_SUCCEEDED(res)) {
     return res;
   }
 
   // paranoia; don't have uninitialized bytes included in data->len()
   data->SetLength(out_len);
 
-  MOZ_MTLOG(ML_DEBUG, pipeline_->description_ << " sending " <<
-            (is_rtp ? "RTP" : "RTCP") << " packet");
+  CSFLogDebug(LOGTAG, "%s sending %s packet", pipeline_->description_.c_str(),
+              (is_rtp ? "RTP" : "RTCP"));
   if (is_rtp) {
     pipeline_->packet_dumper_->Dump(
         pipeline_->level(), dom::mozPacketDumpType::Srtp, true, data->data(), out_len);
 
     pipeline_->increment_rtp_packets_sent(out_len);
   } else {
     pipeline_->packet_dumper_->Dump(
         pipeline_->level(), dom::mozPacketDumpType::Srtcp, true, data->data(), out_len);
@@ -1769,35 +1765,34 @@ UnsetTrackId(MediaStreamGraphImpl* graph
   };
   graph->AppendMessage(MakeUnique<Message>(this));
 }
 // Called if we're attached with AddDirectListener()
 void MediaPipelineTransmit::PipelineListener::
 NotifyRealtimeTrackData(MediaStreamGraph* graph,
                         StreamTime offset,
                         const MediaSegment& media) {
-  MOZ_MTLOG(ML_DEBUG, "MediaPipeline::NotifyRealtimeTrackData() listener=" <<
-                      this << ", offset=" << offset <<
-                      ", duration=" << media.GetDuration());
+  CSFLogDebug(LOGTAG, "MediaPipeline::NotifyRealtimeTrackData() listener=%p, offset=%" PRId64 ", duration=%" PRId64,
+              this, offset, media.GetDuration());
 
   if (media.GetType() == MediaSegment::VIDEO) {
     // We have to call the upstream NotifyRealtimeTrackData and
     // MediaStreamVideoSink will route them to SetCurrentFrames.
     MediaStreamVideoSink::NotifyRealtimeTrackData(graph, offset, media);
     return;
   }
 
   NewData(media, graph->GraphRate());
 }
 
 void MediaPipelineTransmit::PipelineListener::
 NotifyQueuedChanges(MediaStreamGraph* graph,
                     StreamTime offset,
                     const MediaSegment& queued_media) {
-  MOZ_MTLOG(ML_DEBUG, "MediaPipeline::NotifyQueuedChanges()");
+  CSFLogDebug(LOGTAG, "MediaPipeline::NotifyQueuedChanges()");
 
   if (queued_media.GetType() == MediaSegment::VIDEO) {
     // We always get video from SetCurrentFrames().
     return;
   }
 
   if (direct_connect_) {
     // ignore non-direct data if we're also getting direct data
@@ -1811,33 +1806,33 @@ NotifyQueuedChanges(MediaStreamGraph* gr
     // When running tests, graph may be null. In that case use a default.
     rate = 16000;
   }
   NewData(queued_media, rate);
 }
 
 void MediaPipelineTransmit::PipelineListener::
 NotifyDirectListenerInstalled(InstallationResult aResult) {
-  MOZ_MTLOG(ML_INFO, "MediaPipeline::NotifyDirectListenerInstalled() listener= " <<
-                     this << ", result=" << static_cast<int32_t>(aResult));
+  CSFLogInfo(LOGTAG, "MediaPipeline::NotifyDirectListenerInstalled() listener=%p, result=%d",
+             this, static_cast<int32_t>(aResult));
 
   direct_connect_ = InstallationResult::SUCCESS == aResult;
 }
 
 void MediaPipelineTransmit::PipelineListener::
 NotifyDirectListenerUninstalled() {
-  MOZ_MTLOG(ML_INFO, "MediaPipeline::NotifyDirectListenerUninstalled() listener=" << this);
+  CSFLogInfo(LOGTAG, "MediaPipeline::NotifyDirectListenerUninstalled() listener=%p", this);
 
   direct_connect_ = false;
 }
 
 void MediaPipelineTransmit::PipelineListener::
 NewData(const MediaSegment& media, TrackRate aRate /* = 0 */) {
   if (!active_) {
-    MOZ_MTLOG(ML_DEBUG, "Discarding packets because transport not ready");
+    CSFLogDebug(LOGTAG, "Discarding packets because transport not ready");
     return;
   }
 
   if (conduit_->type() !=
       (media.GetType() == MediaSegment::AUDIO ? MediaSessionConduit::AUDIO :
                                                 MediaSessionConduit::VIDEO)) {
     MOZ_ASSERT(false, "The media type should always be correct since the "
                       "listener is locked to a specific track");
@@ -2027,17 +2022,17 @@ public:
     }
   }
 
   // Implement MediaStreamListener
   void NotifyPull(MediaStreamGraph* graph, StreamTime desired_time) override
   {
     MOZ_ASSERT(source_);
     if (!source_) {
-      MOZ_MTLOG(ML_ERROR, "NotifyPull() called from a non-SourceMediaStream");
+      CSFLogError(LOGTAG, "NotifyPull() called from a non-SourceMediaStream");
       return;
     }
 
     // This comparison is done in total time to avoid accumulated roundoff errors.
     while (source_->TicksToTimeRoundDown(WEBRTC_DEFAULT_SAMPLE_RATE,
                                          played_ticks_) < desired_time) {
       int16_t scratch_buffer[AUDIO_SAMPLE_BUFFER_MAX_BYTES / sizeof(int16_t)];
 
@@ -2048,29 +2043,28 @@ public:
           static_cast<AudioSessionConduit*>(conduit_.get())->GetAudioFrame(
               scratch_buffer,
               WEBRTC_DEFAULT_SAMPLE_RATE,
               0,  // TODO(ekr@rtfm.com): better estimate of "capture" (really playout) delay
               samples_length);
 
       if (err != kMediaConduitNoError) {
         // Insert silence on conduit/GIPS failure (extremely unlikely)
-        MOZ_MTLOG(ML_ERROR, "Audio conduit failed (" << err
-                  << ") to return data @ " << played_ticks_
-                  << " (desired " << desired_time << " -> "
-                  << source_->StreamTimeToSeconds(desired_time) << ")");
+        CSFLogError(LOGTAG, "Audio conduit failed (%d) to return data @ %" PRId64 " (desired %" PRId64 " -> %f)",
+                    err, played_ticks_, desired_time,
+                    source_->StreamTimeToSeconds(desired_time));
         // if this is not enough we'll loop and provide more
         samples_length = WEBRTC_DEFAULT_SAMPLE_RATE/100;
         PodArrayZero(scratch_buffer);
       }
 
       MOZ_ASSERT(samples_length * sizeof(uint16_t) < AUDIO_SAMPLE_BUFFER_MAX_BYTES);
 
-      MOZ_MTLOG(ML_DEBUG, "Audio conduit returned buffer of length "
-                << samples_length);
+      CSFLogDebug(LOGTAG, "Audio conduit returned buffer of length %u",
+                  samples_length);
 
       RefPtr<SharedBuffer> samples = SharedBuffer::Create(samples_length * sizeof(uint16_t));
       int16_t *samples_data = static_cast<int16_t *>(samples->Data());
       AudioSegment segment;
       // We derive the number of channels of the stream from the number of samples
       // the AudioConduit gives us, considering it gives us packets of 10ms and we
       // know the rate.
       uint32_t channelCount = samples_length / (WEBRTC_DEFAULT_SAMPLE_RATE / 100);
@@ -2103,17 +2097,17 @@ public:
           if (played_ticks_ > last_log_ + WEBRTC_DEFAULT_SAMPLE_RATE) { // ~ 1 second
             MOZ_LOG(AudioLogModule(), LogLevel::Debug,
                     ("%p: Inserting %zu samples into track %d, total = %" PRIu64,
                      (void*) this, frames, track_id_, played_ticks_));
             last_log_ = played_ticks_;
           }
         }
       } else {
-        MOZ_MTLOG(ML_ERROR, "AppendToTrack failed");
+        CSFLogError(LOGTAG, "AppendToTrack failed");
         // we can't un-read the data, but that's ok since we don't want to
         // buffer - but don't i-loop!
         return;
       }
     }
   }
 
 private:
@@ -2149,17 +2143,17 @@ void MediaPipelineReceiveAudio::DetachMe
     }
     stream_ = nullptr;
   }
 }
 
 nsresult MediaPipelineReceiveAudio::Init()
 {
   ASSERT_ON_THREAD(main_thread_);
-  MOZ_MTLOG(ML_DEBUG, __FUNCTION__);
+  CSFLogDebug(LOGTAG, "%s", __FUNCTION__);
 
   description_ = pc_ + "| Receive audio[";
   description_ += track_id_;
   description_ += "]";
 
   listener_->AddSelf();
 
   return MediaPipelineReceive::Init();
@@ -2197,17 +2191,17 @@ public:
     if (delta > 0) {
       VideoSegment segment;
       IntSize size = image ? image->GetSize() : IntSize(width_, height_);
       segment.AppendFrame(image.forget(), delta, size, principal_handle_);
       // Handle track not actually added yet or removed/finished
       if (source_->AppendToTrack(track_id_, &segment)) {
         played_ticks_ = desired_time;
       } else {
-        MOZ_MTLOG(ML_ERROR, "AppendToTrack failed");
+        CSFLogError(LOGTAG, "AppendToTrack failed");
         return;
       }
     }
   }
 
   // Accessors for external writes from the renderer
   void FrameSizeChange(unsigned int width,
                        unsigned int height,
@@ -2331,17 +2325,17 @@ void MediaPipelineReceiveVideo::DetachMe
     listener_->EndTrack();
     stream_->RemoveListener(listener_);
     stream_ = nullptr;
   }
 }
 
 nsresult MediaPipelineReceiveVideo::Init() {
   ASSERT_ON_THREAD(main_thread_);
-  MOZ_MTLOG(ML_DEBUG, __FUNCTION__);
+  CSFLogDebug(LOGTAG, "%s", __FUNCTION__);
 
   description_ = pc_ + "| Receive video[";
   description_ += track_id_;
   description_ += "]";
 
   listener_->AddSelf();
 
   // Always happens before we can DetachMedia()
--- a/media/webrtc/signaling/src/mediapipeline/MediaPipelineFilter.cpp
+++ b/media/webrtc/signaling/src/mediapipeline/MediaPipelineFilter.cpp
@@ -5,20 +5,24 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 // Original author: bcampen@mozilla.com
 
 #include "MediaPipelineFilter.h"
 
 #include "webrtc/common_types.h"
-#include "logging.h"
+
+#include "CSFLog.h"
 
-// Logging context
-MOZ_MTLOG_MODULE("mediapipeline")
+static const char* mpfLogTag = "MediaPipelineFilter";
+#ifdef LOGTAG
+#undef LOGTAG
+#endif
+#define LOGTAG mpfLogTag
 
 namespace mozilla {
 
 MediaPipelineFilter::MediaPipelineFilter() : correlator_(0) {