Merge m-c to b2g-inbound to fix a CLOSED TREE
authorWes Kocher <wkocher@mozilla.com>
Wed, 04 Sep 2013 18:00:27 -0700
changeset 158559 4fffd0f9a19818a6bb7799d08a96275e21494867
parent 158558 59417b7613c7c84e66671107735dbc94ae7d3056 (current diff)
parent 158459 77ed46bf4c1a98ebdd79e45ffce947d3a92642c3 (diff)
child 158560 bdc733ce66b9beced7f1bae3861e80915cfa674e
push id2961
push userlsblakk@mozilla.com
push dateMon, 28 Oct 2013 21:59:28 +0000
treeherdermozilla-beta@73ef4f13486f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone26.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Merge m-c to b2g-inbound to fix a CLOSED TREE
dom/bindings/Bindings.conf
dom/bindings/test/test_bug907548.html
dom/workers/test/bug911085_worker.js
dom/workers/test/test_bug911085.html
--- a/accessible/public/ia2/Makefile.in
+++ b/accessible/public/ia2/Makefile.in
@@ -62,16 +62,21 @@ MIDL_GENERATED_FILES = \
   $(MIDL_INTERFACES:%.idl=%_p.c) \
   $(MIDL_INTERFACES:%.idl=%_i.c) \
   $(MIDL_INTERFACES:%.idl=%.h) \
   $(MIDL_ENUMS:%.idl=%.h) \
   $(NULL)
 
 EMBED_MANIFEST_AT = 2
 
+INSTALL_TARGETS += midl
+midl_FILES := $(filter %.h %_i.c,$(MIDL_GENERATED_FILES))
+midl_DEST = $(DIST)/include
+midl_TARGET := export
+
 include $(topsrcdir)/config/rules.mk
 
 OS_LIBS = $(call EXPAND_LIBNAME,uuid kernel32 rpcns4 rpcrt4 ole32 oleaut32)
 
 # generate list of to-be-generated files that are missing
 # but ignore special file dlldata.c
 missing:=$(strip $(foreach onefile,$(strip $(subst dlldata.c,,$(MIDL_GENERATED_FILES))),$(if $(wildcard $(onefile)),,$(onefile))))
 
--- a/accessible/public/ia2/moz.build
+++ b/accessible/public/ia2/moz.build
@@ -1,53 +1,9 @@
 # -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # 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/.
 
 MODULE = 'accessibility'
-
-# Please keep this list in sync with the Makefile.in until the rest of that file
-# is ported over.
-midl_interfaces = [
-    'Accessible2',
-    'Accessible2_2',
-    'AccessibleAction',
-    'AccessibleApplication',
-    'AccessibleComponent',
-    'AccessibleDocument',
-    'AccessibleEditableText',
-    'AccessibleHyperlink',
-    'AccessibleHypertext',
-    'AccessibleHypertext2',
-    'AccessibleImage',
-    'AccessibleRelation',
-    'AccessibleTable',
-    'AccessibleTable2',
-    'AccessibleTableCell',
-    'AccessibleText',
-    'AccessibleText2',
-    'AccessibleValue',
-]
-
-# Please keep this list in sync with the Makefile.in until the rest of that file
-# is ported over.
-midl_enums = [
-    'AccessibleEventId',
-    'AccessibleRole',
-    'AccessibleStates',
-    'IA2CommonTypes',
-]
-
-headers = ['%s.h' % x for x in midl_enums]
-interfaces_h = ['%s.h' % x for x in midl_interfaces]
-interfaces_c = ['%s_i.c' % x for x in midl_interfaces]
-
-# The underscore throws off sorting and EXPORTS expects sorted lists.
-interfaces_c.sort()
-
-EXPORTS += headers
-EXPORTS += interfaces_h
-EXPORTS += interfaces_c
-
 LIBRARY_NAME = 'IA2Marshal'
 
--- a/accessible/public/msaa/Makefile.in
+++ b/accessible/public/msaa/Makefile.in
@@ -55,10 +55,24 @@ done_gen: ISimpleDOMNode.idl \
 export:: done_gen
 
 # This marshall dll is also registered in the installer
 register::
 	regsvr32 -s $(DIST)/bin/$(SHARED_LIBRARY)
 
 EMBED_MANIFEST_AT = 2
 
+midl_exports := \
+    ISimpleDOMDocument.h \
+    ISimpleDOMDocument_i.c \
+    ISimpleDOMNode.h \
+    ISimpleDOMNode_i.c \
+    ISimpleDOMText.h \
+    ISimpleDOMText_i.c \
+    $(NULL)
+
+INSTALL_TARGETS += midl_exports
+midl_exports_FILES := $(midl_exports)
+midl_exports_DEST = $(DIST)/include
+midl_exports_TARGET := export
+
 include $(topsrcdir)/config/rules.mk
 
--- a/accessible/public/msaa/moz.build
+++ b/accessible/public/msaa/moz.build
@@ -1,19 +1,10 @@
 # -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # 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/.
 
 MODULE = 'accessibility'
 
-EXPORTS += [
-    'ISimpleDOMDocument.h',
-    'ISimpleDOMDocument_i.c',
-    'ISimpleDOMNode.h',
-    'ISimpleDOMNode_i.c',
-    'ISimpleDOMText.h',
-    'ISimpleDOMText_i.c',
-]
-
 LIBRARY_NAME = 'AccessibleMarshal'
 
--- a/accessible/src/xpcom/Makefile.in
+++ b/accessible/src/xpcom/Makefile.in
@@ -6,16 +6,21 @@ DEPTH = @DEPTH@
 topsrcdir = @top_srcdir@
 srcdir = @srcdir@
 VPATH = @srcdir@
 
 include $(DEPTH)/config/autoconf.mk
 
 EXTRA_MDDEPEND_FILES = xpcAccEvents.pp
 
+INSTALL_TARGETS += xpcaccevents
+xpcaccevents_FILES := xpcAccEvents.h
+xpcaccevents_DEST = $(DIST)/include
+xpcaccevents_TARGET := export
+
 include $(topsrcdir)/config/rules.mk
 
 LOCAL_INCLUDES = \
   -I$(srcdir)/../base \
   -I$(srcdir)/../generic \
   $(NULL)
 
 ifdef MOZ_ENABLE_GTK
--- a/accessible/src/xpcom/moz.build
+++ b/accessible/src/xpcom/moz.build
@@ -1,20 +1,16 @@
 # -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # 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/.
 
 MODULE = 'accessibility'
 
-EXPORTS += [
-    'xpcAccEvents.h',
-]
-
 CPP_SOURCES += [
     'nsAccessibleRelation.cpp',
     'xpcAccEvents.cpp',
     'xpcAccessibleTable.cpp',
     'xpcAccessibleTableCell.cpp',
 ]
 
 LIBRARY_NAME = 'accessibility_xpcom_s'
--- a/browser/app/profile/firefox.js
+++ b/browser/app/profile/firefox.js
@@ -1070,16 +1070,17 @@ pref("devtools.toolbox.selectedTool", "w
 pref("devtools.toolbox.toolbarSpec", '["paintflashing toggle","tilt toggle","scratchpad","resize toggle"]');
 pref("devtools.toolbox.sideEnabled", true);
 
 // Enable the Inspector
 pref("devtools.inspector.enabled", true);
 pref("devtools.inspector.activeSidebar", "ruleview");
 pref("devtools.inspector.markupPreview", false);
 pref("devtools.inspector.remote", false);
+pref("devtools.inspector.show_pseudo_elements", true);
 
 // Enable the Layout View
 pref("devtools.layoutview.enabled", true);
 pref("devtools.layoutview.open", false);
 
 // Enable the Responsive UI tool
 pref("devtools.responsiveUI.enabled", true);
 pref("devtools.responsiveUI.no-reload-notification", false);
--- a/browser/base/content/browser-social.js
+++ b/browser/base/content/browser-social.js
@@ -32,16 +32,20 @@ SocialUI = {
   init: function SocialUI_init() {
     Services.obs.addObserver(this, "social:ambient-notification-changed", false);
     Services.obs.addObserver(this, "social:profile-changed", false);
     Services.obs.addObserver(this, "social:page-mark-config", false);
     Services.obs.addObserver(this, "social:frameworker-error", false);
     Services.obs.addObserver(this, "social:provider-set", false);
     Services.obs.addObserver(this, "social:providers-changed", false);
     Services.obs.addObserver(this, "social:provider-reload", false);
+    Services.obs.addObserver(this, "social:provider-installed", false);
+    Services.obs.addObserver(this, "social:provider-uninstalled", false);
+    Services.obs.addObserver(this, "social:provider-enabled", false);
+    Services.obs.addObserver(this, "social:provider-disabled", false);
 
     Services.prefs.addObserver("social.sidebar.open", this, false);
     Services.prefs.addObserver("social.toast-notifications.enabled", this, false);
 
     gBrowser.addEventListener("ActivateSocialFeature", this._activationEventHandler.bind(this), true, true);
 
     if (!Social.initialized) {
       Social.init();
@@ -57,30 +61,46 @@ SocialUI = {
   uninit: function SocialUI_uninit() {
     Services.obs.removeObserver(this, "social:ambient-notification-changed");
     Services.obs.removeObserver(this, "social:profile-changed");
     Services.obs.removeObserver(this, "social:page-mark-config");
     Services.obs.removeObserver(this, "social:frameworker-error");
     Services.obs.removeObserver(this, "social:provider-set");
     Services.obs.removeObserver(this, "social:providers-changed");
     Services.obs.removeObserver(this, "social:provider-reload");
+    Services.obs.removeObserver(this, "social:provider-installed");
+    Services.obs.removeObserver(this, "social:provider-uninstalled");
+    Services.obs.removeObserver(this, "social:provider-enabled");
+    Services.obs.removeObserver(this, "social:provider-disabled");
 
     Services.prefs.removeObserver("social.sidebar.open", this);
     Services.prefs.removeObserver("social.toast-notifications.enabled", this);
   },
 
   _matchesCurrentProvider: function (origin) {
     return Social.provider && Social.provider.origin == origin;
   },
 
   observe: function SocialUI_observe(subject, topic, data) {
     // Exceptions here sometimes don't get reported properly, report them
     // manually :(
     try {
       switch (topic) {
+        case "social:provider-installed":
+          SocialStatus.setPosition(data);
+          break;
+        case "social:provider-uninstalled":
+          SocialStatus.removePosition(data);
+          break;
+        case "social:provider-enabled":
+          SocialStatus.populateToolbarPalette();
+          break;
+        case "social:provider-disabled":
+          SocialStatus.removeProvider(data);
+          break;
         case "social:provider-reload":
           // if the reloaded provider is our current provider, fall through
           // to social:provider-set so the ui will be reset
           if (!Social.provider || Social.provider.origin != data)
             return;
           // be sure to unload the sidebar as it will not reload if the origin
           // has not changed, it will be loaded in provider-set below. Other
           // panels will be unloaded or handle reload.
@@ -93,28 +113,31 @@ SocialUI = {
           this._updateMenuItems();
 
           SocialFlyout.unload();
           SocialChatBar.update();
           SocialShare.update();
           SocialSidebar.update();
           SocialMark.update();
           SocialToolbar.update();
+          SocialStatus.populateToolbarPalette();
           SocialMenu.populate();
           break;
         case "social:providers-changed":
           // the list of providers changed - this may impact the "active" UI.
           this._updateActiveUI();
           // and the multi-provider menu
           SocialToolbar.populateProviderMenus();
           SocialShare.populateProviderMenu();
+          SocialStatus.populateToolbarPalette();
           break;
 
         // Provider-specific notifications
         case "social:ambient-notification-changed":
+          SocialStatus.updateNotification(data);
           if (this._matchesCurrentProvider(data)) {
             SocialToolbar.updateButton();
             SocialMenu.populate();
           }
           break;
         case "social:profile-changed":
           if (this._matchesCurrentProvider(data)) {
             SocialToolbar.updateProvider();
@@ -1051,16 +1074,25 @@ SocialToolbar = {
         (!Social.provider.haveLoggedInUser() && Social.provider.profile !== undefined)) {
       // Either no enabled provider, or there is a provider and it has
       // responded with a profile and the user isn't loggedin.  The icons
       // etc have already been removed by updateButtonHiddenState, so we want
       // to nuke any cached icons we have and get out of here!
       Services.prefs.clearUserPref(CACHE_PREF_NAME);
       return;
     }
+
+    // If the provider uses the new SocialStatus button, then they do not get
+    // to use the ambient icons in the old toolbar button.  Since the status
+    // button depends on multiple workers, if not enabled we will ignore this
+    // limitation.  That allows a provider to migrate to the new functionality
+    // once we enable multiple workers.
+    if (Social.provider.statusURL && Social.allowMultipleWorkers)
+      return;
+
     let icons = Social.provider.ambientNotificationIcons;
     let iconNames = Object.keys(icons);
 
     if (Social.provider.profile === undefined) {
       // provider has not told us about the login state yet - see if we have
       // a cached version for this provider.
       let cached;
       try {
@@ -1149,19 +1181,18 @@ SocialToolbar = {
         ariaLabel = gNavigatorBundle.getFormattedString("social.aria.toolbarButtonBadgeText",
                                                         [ariaLabel, badge]);
       toolbarButton.setAttribute("aria-label", ariaLabel);
     }
     let socialToolbarItem = document.getElementById("social-toolbar-item");
     socialToolbarItem.insertBefore(toolbarButtons, SocialMark.button);
 
     for (let frame of createdFrames) {
-      if (frame.socialErrorListener) {
+      if (frame.socialErrorListener)
         frame.socialErrorListener.remove();
-      }
       if (frame.docShell) {
         frame.docShell.isActive = false;
         Social.setErrorListener(frame, this.setPanelErrorMessage.bind(this));
       }
     }
   },
 
   showAmbientPopup: function SocialToolbar_showAmbientPopup(aToolbarButton) {
@@ -1196,21 +1227,20 @@ SocialToolbar = {
       aToolbarButton.parentNode.removeAttribute("open");
       dynamicResizer.stop();
       notificationFrame.docShell.isActive = false;
       dispatchPanelEvent("socialFrameHide");
     });
 
     panel.addEventListener("popupshown", function onpopupshown() {
       panel.removeEventListener("popupshown", onpopupshown);
-      // This attribute is needed on both the button and the
-      // containing toolbaritem since the buttons on OS X have
-      // moz-appearance:none, while their container gets
-      // moz-appearance:toolbarbutton due to the way that toolbar buttons
-      // get combined on OS X.
+      // The "open" attribute is needed on both the button and the containing
+      // toolbaritem since the buttons on OS X have moz-appearance:none, while
+      // their container gets moz-appearance:toolbarbutton due to the way that
+      // toolbar buttons get combined on OS X.
       aToolbarButton.setAttribute("open", "true");
       aToolbarButton.parentNode.setAttribute("open", "true");
       notificationFrame.docShell.isActive = true;
       notificationFrame.docShell.isAppTab = true;
       if (notificationFrame.contentDocument.readyState == "complete" && wasAlive) {
         dynamicResizer.start(panel, notificationFrame);
         dispatchPanelEvent("socialFrameShow");
       } else {
@@ -1387,9 +1417,358 @@ SocialSidebar = {
       sbrowser.setAttribute("src", "about:socialerror?mode=workerFailure");
     } else {
       let url = encodeURIComponent(Social.provider.sidebarURL);
       sbrowser.loadURI("about:socialerror?mode=tryAgain&url=" + url, null, null);
     }
   }
 }
 
+// this helper class is used by removable/customizable buttons to handle
+// location persistence and insertion into palette and/or toolbars
+
+// When a provider is installed we show all their UI so the user will see the
+// functionality of what they installed. The user can later customize the UI,
+// moving buttons around or off the toolbar.
+//
+// To make this happen, on install we add a button id to the navbar currentset.
+// On enabling the provider (happens just after install) we insert the button
+// into the toolbar as well. The button is then persisted on restart (assuming
+// it was not removed).
+//
+// When a provider is disabled, we do not remove the buttons from currentset.
+// That way, if the provider is re-enabled during the same session, the buttons
+// will reappear where they were before. When a provider is uninstalled, we make
+// sure that the id is removed from currentset.
+//
+// On startup, we insert the buttons of any enabled provider into either the
+// apropriate toolbar or the palette.
+function ToolbarHelper(type, createButtonFn) {
+  this._createButton = createButtonFn;
+  this._type = type;
+}
+
+ToolbarHelper.prototype = {
+  idFromOrgin: function(origin) {
+    return this._type + "-" + origin;
+  },
+
+  // find a button either in the document or the palette
+  _getExistingButton: function(id) {
+    let button = document.getElementById(id);
+    if (button)
+      return button;
+    let palette = document.getElementById("navigator-toolbox").palette;
+    let paletteItem = palette.firstChild;
+    while (paletteItem) {
+      if (paletteItem.id == id)
+        return paletteItem;
+      paletteItem = paletteItem.nextSibling;
+    }
+    return null;
+  },
+
+  setPersistentPosition: function(id) {
+    // called when a provider is installed.  add provider buttons to nav-bar
+    let toolbar = document.getElementById("nav-bar");
+    // first startups will not have a currentset attribute, always rely on
+    // currentSet since it will be derived from the defaultset in that case.
+    let currentset = toolbar.currentSet;
+    if (currentset == "__empty")
+      currentset = []
+    else
+      currentset = currentset.split(",");
+    if (currentset.indexOf(id) >= 0)
+      return;
+    // we do not set toolbar.currentSet since that will try to add the button,
+    // and we have not added it yet (happens on provider being enabled)
+    currentset.push(id);
+    toolbar.setAttribute("currentset", currentset.join(","));
+    document.persist(toolbar.id, "currentset");
+  },
+
+  removeProviderButton: function(origin) {
+    // this will remove the button from the palette or the toolbar
+    let button = this._getExistingButton(this.idFromOrgin(origin));
+    if (button)
+      button.parentNode.removeChild(button);
+  },
+
+  removePersistence: function(id) {
+    let persisted = document.querySelectorAll("*[currentset]");
+    for (let pent of persisted) {
+      // the button will have been removed, but left in the currentset attribute
+      // in case the user re-enables (e.g. undo in addon manager). So we only
+      // check the attribute here.
+      let currentset = pent.getAttribute("currentset").split(",");
+
+      let pos = currentset.indexOf(id);
+      if (pos >= 0) {
+        currentset.splice(pos, 1);
+        pent.setAttribute("currentset", currentset.join(","));
+        document.persist(pent.id, "currentset");
+        return;
+      }
+    }
+  },
+
+  // if social is entirely disabled, we need to clear the palette, but leave
+  // the persisted id's in place
+  clearPalette: function() {
+    [this.removeProviderButton(p.origin) for (p of Social.providers)];
+  },
+
+  // should be called on startup of each window, otherwise the addon manager
+  // listener will handle new activations, or enable/disabling of a provider
+  // XXX we currently call more regularly, will fix during refactoring
+  populatePalette: function() {
+    if (!Social.enabled) {
+      this.clearPalette();
+      return;
+    }
+    let persisted = document.querySelectorAll("*[currentset]");
+    let persistedById = {};
+    for (let pent of persisted) {
+      let pset = pent.getAttribute("currentset").split(',');
+      for (let id of pset)
+        persistedById[id] = pent;
+    }
+
+    // create any buttons that do not exist yet if they have been persisted
+    // as a part of the UI (otherwise they belong in the palette).
+    for (let provider of Social.providers) {
+      let id = this.idFromOrgin(provider.origin);
+      if (this._getExistingButton(id))
+        return;
+      let button = this._createButton(provider);
+      if (button && persistedById.hasOwnProperty(id)) {
+        let parent = persistedById[id];
+        let pset = persistedById[id].getAttribute("currentset").split(',');
+        let pi = pset.indexOf(id) + 1;
+        let next = document.getElementById(pset[pi]);
+        parent.insertItem(id, next, null, false);
+      }
+    }
+  }
+}
+
+SocialStatus = {
+  populateToolbarPalette: function() {
+    if (!Social.allowMultipleWorkers)
+      return;
+    this._toolbarHelper.populatePalette();
+  },
+
+  setPosition: function(origin) {
+    if (!Social.allowMultipleWorkers)
+      return;
+    // this is called during install, before the provider is enabled so we have
+    // to use the manifest rather than the provider instance as we do elsewhere.
+    let manifest = Social.getManifestByOrigin(origin);
+    if (!manifest.statusURL)
+      return;
+    let tbh = this._toolbarHelper;
+    tbh.setPersistentPosition(tbh.idFromOrgin(origin));
+  },
+
+  removePosition: function(origin) {
+    if (!Social.allowMultipleWorkers)
+      return;
+    let tbh = this._toolbarHelper;
+    tbh.removePersistence(tbh.idFromOrgin(origin));
+  },
+
+  removeProvider: function(origin) {
+    if (!Social.allowMultipleWorkers)
+      return;
+    this._toolbarHelper.removeProviderButton(origin);
+  },
+
+  get _toolbarHelper() {
+    delete this._toolbarHelper;
+    this._toolbarHelper = new ToolbarHelper("social-status-button", this._createButton.bind(this));
+    return this._toolbarHelper;
+  },
+
+  get _dynamicResizer() {
+    delete this._dynamicResizer;
+    this._dynamicResizer = new DynamicResizeWatcher();
+    return this._dynamicResizer;
+  },
+
+  _createButton: function(provider) {
+    if (!provider.statusURL)
+      return null;
+    let palette = document.getElementById("navigator-toolbox").palette;
+    let button = document.createElement("toolbarbutton");
+    button.setAttribute("class", "toolbarbutton-1 social-status-button");
+    button.setAttribute("type", "badged");
+    button.setAttribute("removable", "true");
+    button.setAttribute("image", provider.iconURL);
+    button.setAttribute("label", provider.name);
+    button.setAttribute("tooltiptext", provider.name);
+    button.setAttribute("origin", provider.origin);
+    button.setAttribute("oncommand", "SocialStatus.showPopup(this);");
+    button.setAttribute("id", this._toolbarHelper.idFromOrgin(provider.origin));
+    palette.appendChild(button);
+    return button;
+  },
+
+  // status panels are one-per button per-process, we swap the docshells between
+  // windows when necessary
+  _attachNotificatonPanel: function(aButton, provider) {
+    let panel = document.getElementById("social-notification-panel");
+    panel.hidden = !SocialUI.enabled;
+    let notificationFrameId = "social-status-" + provider.origin;
+    let frame = document.getElementById(notificationFrameId);
+
+    if (!frame) {
+      frame = SharedFrame.createFrame(
+        notificationFrameId, /* frame name */
+        panel, /* parent */
+        {
+          "type": "content",
+          "mozbrowser": "true",
+          "class": "social-panel-frame",
+          "id": notificationFrameId,
+          "tooltip": "aHTMLTooltip",
+
+          // work around bug 793057 - by making the panel roughly the final size
+          // we are more likely to have the anchor in the correct position.
+          "style": "width: " + PANEL_MIN_WIDTH + "px;",
+
+          "origin": provider.origin,
+          "src": provider.statusURL
+        }
+      );
+
+      if (frame.socialErrorListener)
+        frame.socialErrorListener.remove();
+      if (frame.docShell) {
+        frame.docShell.isActive = false;
+        Social.setErrorListener(frame, this.setPanelErrorMessage.bind(this));
+      }
+    } else {
+      frame.setAttribute("origin", provider.origin);
+      SharedFrame.updateURL(notificationFrameId, provider.statusURL);
+    }
+    aButton.setAttribute("notificationFrameId", notificationFrameId);
+  },
+
+  updateNotification: function(origin) {
+    if (!Social.allowMultipleWorkers)
+      return;
+    let provider = Social._getProviderFromOrigin(origin);
+    let button = document.getElementById(this._toolbarHelper.idFromOrgin(provider.origin));
+    if (button) {
+      // we only grab the first notification, ignore all others
+      let icons = provider.ambientNotificationIcons;
+      let iconNames = Object.keys(icons);
+      let notif = icons[iconNames[0]];
+      if (!notif) {
+        button.setAttribute("badge", "");
+        button.setAttribute("aria-label", "");
+        button.setAttribute("tooltiptext", "");
+        return;
+      }
+
+      button.style.listStyleImage = "url(" + notif.iconURL || provider.iconURL + ")";
+      button.setAttribute("tooltiptext", notif.label);
+
+      let badge = notif.counter || "";
+      button.setAttribute("badge", badge);
+      let ariaLabel = notif.label;
+      // if there is a badge value, we must use a localizable string to insert it.
+      if (badge)
+        ariaLabel = gNavigatorBundle.getFormattedString("social.aria.toolbarButtonBadgeText",
+                                                        [ariaLabel, badge]);
+      button.setAttribute("aria-label", ariaLabel);
+    }
+  },
+
+  showPopup: function(aToolbarButton) {
+    if (!Social.allowMultipleWorkers)
+      return;
+    // attach our notification panel if necessary
+    let origin = aToolbarButton.getAttribute("origin");
+    let provider = Social._getProviderFromOrigin(origin);
+    this._attachNotificatonPanel(aToolbarButton, provider);
+
+    let panel = document.getElementById("social-notification-panel");
+    let notificationFrameId = aToolbarButton.getAttribute("notificationFrameId");
+    let notificationFrame = document.getElementById(notificationFrameId);
+
+    let wasAlive = SharedFrame.isGroupAlive(notificationFrameId);
+    SharedFrame.setOwner(notificationFrameId, notificationFrame);
+
+    // Clear dimensions on all browsers so the panel size will
+    // only use the selected browser.
+    let frameIter = panel.firstElementChild;
+    while (frameIter) {
+      frameIter.collapsed = (frameIter != notificationFrame);
+      frameIter = frameIter.nextElementSibling;
+    }
+
+    function dispatchPanelEvent(name) {
+      let evt = notificationFrame.contentDocument.createEvent("CustomEvent");
+      evt.initCustomEvent(name, true, true, {});
+      notificationFrame.contentDocument.documentElement.dispatchEvent(evt);
+    }
+
+    let dynamicResizer = this._dynamicResizer;
+    panel.addEventListener("popuphidden", function onpopuphiding() {
+      panel.removeEventListener("popuphidden", onpopuphiding);
+      aToolbarButton.removeAttribute("open");
+      dynamicResizer.stop();
+      notificationFrame.docShell.isActive = false;
+      dispatchPanelEvent("socialFrameHide");
+    });
+
+    panel.addEventListener("popupshown", function onpopupshown() {
+      panel.removeEventListener("popupshown", onpopupshown);
+      // This attribute is needed on both the button and the
+      // containing toolbaritem since the buttons on OS X have
+      // moz-appearance:none, while their container gets
+      // moz-appearance:toolbarbutton due to the way that toolbar buttons
+      // get combined on OS X.
+      aToolbarButton.setAttribute("open", "true");
+      notificationFrame.docShell.isActive = true;
+      notificationFrame.docShell.isAppTab = true;
+      if (notificationFrame.contentDocument.readyState == "complete" && wasAlive) {
+        dynamicResizer.start(panel, notificationFrame);
+        dispatchPanelEvent("socialFrameShow");
+      } else {
+        // first time load, wait for load and dispatch after load
+        notificationFrame.addEventListener("load", function panelBrowserOnload(e) {
+          notificationFrame.removeEventListener("load", panelBrowserOnload, true);
+          dynamicResizer.start(panel, notificationFrame);
+          dispatchPanelEvent("socialFrameShow");
+        }, true);
+      }
+    });
+
+    let navBar = document.getElementById("nav-bar");
+    let anchor = navBar.getAttribute("mode") == "text" ?
+                   document.getAnonymousElementByAttribute(aToolbarButton, "class", "toolbarbutton-text") :
+                   document.getAnonymousElementByAttribute(aToolbarButton, "class", "toolbarbutton-badge-container");
+    // Bug 849216 - open the popup in a setTimeout so we avoid the auto-rollup
+    // handling from preventing it being opened in some cases.
+    setTimeout(function() {
+      panel.openPopup(anchor, "bottomcenter topright", 0, 0, false, false);
+    }, 0);
+  },
+
+  setPanelErrorMessage: function(aNotificationFrame) {
+    if (!aNotificationFrame)
+      return;
+
+    let src = aNotificationFrame.getAttribute("src");
+    aNotificationFrame.removeAttribute("src");
+    aNotificationFrame.webNavigation.loadURI("about:socialerror?mode=tryAgainOnly&url=" +
+                                             encodeURIComponent(src),
+                                             null, null, null, null);
+    let panel = aNotificationFrame.parentNode;
+    sizeSocialPanelToContent(panel, aNotificationFrame);
+  },
+
+};
+
 })();
--- a/browser/base/content/browser.js
+++ b/browser/base/content/browser.js
@@ -2209,19 +2209,20 @@ function losslessDecodeURI(aURI) {
                 //    ';', '/', '?', ':', '@', '&', '=', '+', '$', ',', '#'
                 //    (RFC 3987 section 3.2)
                 // 2. Re-encode whitespace so that it doesn't get eaten away
                 //    by the location bar (bug 410726).
                 .replace(/%(?!3B|2F|3F|3A|40|26|3D|2B|24|2C|23)|[\r\n\t]/ig,
                          encodeURIComponent);
     } catch (e) {}
 
-  // Encode invisible characters (line and paragraph separator,
-  // object replacement character) (bug 452979)
-  value = value.replace(/[\v\x0c\x1c\x1d\x1e\x1f\u2028\u2029\ufffc]/g,
+  // Encode invisible characters (C0/C1 control characters, U+007F [DEL],
+  // U+00A0 [no-break space], line and paragraph separator,
+  // object replacement character) (bug 452979, bug 909264)
+  value = value.replace(/[\u0000-\u001f\u007f-\u00a0\u2028\u2029\ufffc]/g,
                         encodeURIComponent);
 
   // Encode default ignorable characters (bug 546013)
   // except ZWNJ (U+200C) and ZWJ (U+200D) (bug 582186).
   // This includes all bidirectional formatting characters.
   // (RFC 3987 sections 3.2 and 4.1 paragraph 6)
   value = value.replace(/[\u00ad\u034f\u115f-\u1160\u17b4-\u17b5\u180b-\u180d\u200b\u200e-\u200f\u202a-\u202e\u2060-\u206f\u3164\ufe00-\ufe0f\ufeff\uffa0\ufff0-\ufff8]|\ud834[\udd73-\udd7a]|[\udb40-\udb43][\udc00-\udfff]/g,
                         encodeURIComponent);
--- a/browser/base/content/test/social/Makefile.in
+++ b/browser/base/content/test/social/Makefile.in
@@ -26,16 +26,17 @@ MOCHITEST_BROWSER_FILES = \
                  browser_social_mozSocial_API.js \
                  browser_social_isVisible.js \
                  browser_social_chatwindow.js \
                  browser_social_chatwindow_resize.js \
                  browser_social_chatwindowfocus.js \
                  browser_social_multiprovider.js \
                  browser_social_multiworker.js \
                  browser_social_errorPage.js \
+                 browser_social_status.js \
                  browser_social_window.js \
                  social_activate.html \
                  social_activate_iframe.html \
                  browser_share.js \
                  social_panel.html \
                  social_mark_image.png \
                  social_sidebar.html \
                  social_chat.html \
--- a/browser/base/content/test/social/browser_addons.js
+++ b/browser/base/content/test/social/browser_addons.js
@@ -45,19 +45,20 @@ function test() {
     finish();
   });
 }
 
 function installListener(next, aManifest) {
   let expectEvent = "onInstalling";
   let prefname = getManifestPrefname(aManifest);
   // wait for the actual removal to call next
-  SocialService.registerProviderListener(function providerListener(topic, data) {
-    if (topic == "provider-removed") {
+  SocialService.registerProviderListener(function providerListener(topic, origin, providers) {
+    if (topic == "provider-disabled") {
       SocialService.unregisterProviderListener(providerListener);
+      is(origin, aManifest.origin, "provider disabled");
       executeSoon(next);
     }
   });
 
   return {
     onInstalling: function(addon) {
       is(expectEvent, "onInstalling", "install started");
       is(addon.manifest.origin, aManifest.origin, "provider about to be installed");
@@ -290,24 +291,25 @@ var tests = {
       let installFrom = doc.nodePrincipal.origin;
       Services.prefs.setCharPref("social.whitelist", installFrom);
       Social.installProvider(doc, manifest2, function(addonManifest) {
         SocialService.addBuiltinProvider(addonManifest.origin, function(provider) {
           is(provider.manifest.version, 1, "manifest version is 1");
           Social.enabled = true;
 
           // watch for the provider-update and test the new version
-          SocialService.registerProviderListener(function providerListener(topic, data) {
+          SocialService.registerProviderListener(function providerListener(topic, origin, providers) {
             if (topic != "provider-update")
               return;
+            is(origin, addonManifest.origin, "provider updated")
             SocialService.unregisterProviderListener(providerListener);
             Services.prefs.clearUserPref("social.whitelist");
-            let provider = Social._getProviderFromOrigin(addonManifest.origin);
+            let provider = Social._getProviderFromOrigin(origin);
             is(provider.manifest.version, 2, "manifest version is 2");
-            Social.uninstallProvider(addonManifest.origin, function() {
+            Social.uninstallProvider(origin, function() {
               gBrowser.removeTab(tab);
               next();
             });
           });
 
           let port = provider.getWorkerPort();
           port.onmessage = function (e) {
             let topic = e.data.topic;
--- a/browser/base/content/test/social/browser_blocklist.js
+++ b/browser/base/content/test/social/browser_blocklist.js
@@ -150,24 +150,25 @@ var tests = {
       onWindowTitleChange: function(aXULWindow, aNewTitle) { }
     };
 
     Services.wm.addListener(listener);
 
     setManifestPref("social.manifest.blocked", manifest_bad);
     try {
       SocialService.addProvider(manifest_bad, function(provider) {
-        // the act of blocking should cause a 'provider-removed' notification
+        // the act of blocking should cause a 'provider-disabled' notification
         // from SocialService.
-        SocialService.registerProviderListener(function providerListener(topic) {
-          if (topic != "provider-removed")
+        SocialService.registerProviderListener(function providerListener(topic, origin, providers) {
+          if (topic != "provider-disabled")
             return;
           SocialService.unregisterProviderListener(providerListener);
+          is(origin, provider.origin, "provider disabled");
           SocialService.getProvider(provider.origin, function(p) {
-            ok(p==null, "blocklisted provider removed");
+            ok(p == null, "blocklisted provider disabled");
             Services.prefs.clearUserPref("social.manifest.blocked");
             resetBlocklist(finish);
           });
         });
         // no callback - the act of updating should cause the listener above
         // to fire.
         setAndUpdateBlocklist(blocklistURL);
       });
--- a/browser/base/content/test/social/browser_social_mozSocial_API.js
+++ b/browser/base/content/test/social/browser_social_mozSocial_API.js
@@ -14,16 +14,23 @@ function test() {
   };
   runSocialTestWithProvider(manifest, function (finishcb) {
     runSocialTests(tests, undefined, undefined, finishcb);
   });
 }
 
 var tests = {
   testStatusIcons: function(next) {
+    let icon = {
+      name: "testIcon",
+      iconURL: "chrome://browser/skin/Info.png",
+      contentPanel: "https://example.com/browser/browser/base/content/test/social/social_panel.html",
+      counter: 1
+    };
+
     let iconsReady = false;
     let gotSidebarMessage = false;
 
     function checkNext() {
       if (iconsReady && gotSidebarMessage)
         triggerIconPanel();
     }
 
@@ -66,16 +73,16 @@ var tests = {
             next();
           }
           break;
         case "got-sidebar-message":
           // The sidebar message will always come first, since it loads by default
           ok(true, "got sidebar message");
           gotSidebarMessage = true;
           // load a status panel
-          port.postMessage({topic: "test-ambient-notification"});
+          port.postMessage({topic: "test-ambient-notification", data: icon});
           checkNext();
           break;
       }
     }
     port.postMessage({topic: "test-init"});
   }
 }
new file mode 100644
--- /dev/null
+++ b/browser/base/content/test/social/browser_social_status.js
@@ -0,0 +1,220 @@
+/* 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/. */
+
+let SocialService = Cu.import("resource://gre/modules/SocialService.jsm", {}).SocialService;
+
+let manifest = { // builtin provider
+  name: "provider example.com",
+  origin: "https://example.com",
+  sidebarURL: "https://example.com/browser/browser/base/content/test/social/social_sidebar.html",
+  workerURL: "https://example.com/browser/browser/base/content/test/social/social_worker.js",
+  iconURL: "https://example.com/browser/browser/base/content/test/moz.png"
+};
+let manifest2 = { // used for testing install
+  name: "provider test1",
+  origin: "https://test1.example.com",
+  workerURL: "https://test1.example.com/browser/browser/base/content/test/social/social_worker.js",
+  statusURL: "https://test1.example.com/browser/browser/base/content/test/social/social_panel.html",
+  iconURL: "https://test1.example.com/browser/browser/base/content/test/moz.png",
+  version: 1
+};
+let manifest3 = { // used for testing install
+  name: "provider test2",
+  origin: "https://test2.example.com",
+  sidebarURL: "https://test2.example.com/browser/browser/base/content/test/social/social_sidebar.html",
+  iconURL: "https://test2.example.com/browser/browser/base/content/test/moz.png",
+  version: 1
+};
+
+
+function openWindowAndWaitForInit(callback) {
+  let topic = "browser-delayed-startup-finished";
+  let w = OpenBrowserWindow();
+  Services.obs.addObserver(function providerSet(subject, topic, data) {
+    Services.obs.removeObserver(providerSet, topic);
+    executeSoon(() => callback(w));
+  }, topic, false);
+}
+
+function test() {
+  waitForExplicitFinish();
+
+  Services.prefs.setBoolPref("social.allowMultipleWorkers", true);
+  let toolbar = document.getElementById("nav-bar");
+  let currentsetAtStart = toolbar.currentSet;
+  info("tb0 "+currentsetAtStart);
+  runSocialTestWithProvider(manifest, function () {
+    runSocialTests(tests, undefined, undefined, function () {
+      Services.prefs.clearUserPref("social.remote-install.enabled");
+      // just in case the tests failed, clear these here as well
+      Services.prefs.clearUserPref("social.allowMultipleWorkers");
+      Services.prefs.clearUserPref("social.whitelist");
+      
+      // This post-test test ensures that a new window maintains the same
+      // toolbar button set as when we started. That means our insert/removal of
+      // persistent id's is working correctly
+      is(currentsetAtStart, toolbar.currentSet, "toolbar currentset unchanged");
+      openWindowAndWaitForInit(function(w1) {
+        checkSocialUI(w1);
+        // Sometimes the new window adds other buttons to currentSet that are
+        // outside the scope of what we're checking. So we verify that all
+        // buttons from startup are in currentSet for a new window, and that the
+        // provider buttons are properly removed. (e.g on try, window-controls
+        // was not present in currentsetAtStart, but present on the second
+        // window)
+        let tb1 = w1.document.getElementById("nav-bar");
+        info("tb0 "+toolbar.currentSet);
+        info("tb1 "+tb1.currentSet);
+        let startupSet = Set(toolbar.currentSet.split(','));
+        let newSet = Set(tb1.currentSet.split(','));
+        let intersect = Set([x for (x of startupSet) if (newSet.has(x))]);
+        info("intersect "+intersect);
+        let difference = Set([x for (x of newSet) if (!startupSet.has(x))]);
+        info("difference "+difference);
+        is(startupSet.size, intersect.size, "new window toolbar same as old");
+        // verify that our provider buttons are not in difference
+        let id = SocialStatus._toolbarHelper.idFromOrgin(manifest2.origin);
+        ok(!difference.has(id), "status button not persisted at end");
+        w1.close();
+        finish();
+      });
+    });
+  });
+}
+
+var tests = {
+  testNoButtonOnInstall: function(next) {
+    // we expect the addon install dialog to appear, we need to accept the
+    // install from the dialog.
+    info("Waiting for install dialog");
+    let panel = document.getElementById("servicesInstall-notification");
+    PopupNotifications.panel.addEventListener("popupshown", function onpopupshown() {
+      PopupNotifications.panel.removeEventListener("popupshown", onpopupshown);
+      info("servicesInstall-notification panel opened");
+      panel.button.click();
+    })
+
+    let id = "social-status-button-" + manifest3.origin;
+    let toolbar = document.getElementById("nav-bar");
+    let currentset = toolbar.getAttribute("currentset").split(',');
+    ok(currentset.indexOf(id) < 0, "button is not part of currentset at start");
+
+    let activationURL = manifest3.origin + "/browser/browser/base/content/test/social/social_activate.html"
+    addTab(activationURL, function(tab) {
+      let doc = tab.linkedBrowser.contentDocument;
+      Social.installProvider(doc, manifest3, function(addonManifest) {
+        // enable the provider so we know the button would have appeared
+        SocialService.addBuiltinProvider(manifest3.origin, function(provider) {
+          ok(provider, "provider is installed");
+          currentset = toolbar.getAttribute("currentset").split(',');
+          ok(currentset.indexOf(id) < 0, "button was not added to currentset");
+          Social.uninstallProvider(manifest3.origin, function() {
+            gBrowser.removeTab(tab);
+            next();
+          });
+        });
+      });
+    });
+  },
+  testButtonOnInstall: function(next) {
+    // we expect the addon install dialog to appear, we need to accept the
+    // install from the dialog.
+    info("Waiting for install dialog");
+    let panel = document.getElementById("servicesInstall-notification");
+    PopupNotifications.panel.addEventListener("popupshown", function onpopupshown() {
+      PopupNotifications.panel.removeEventListener("popupshown", onpopupshown);
+      info("servicesInstall-notification panel opened");
+      panel.button.click();
+    })
+
+    let activationURL = manifest2.origin + "/browser/browser/base/content/test/social/social_activate.html"
+    addTab(activationURL, function(tab) {
+      let doc = tab.linkedBrowser.contentDocument;
+      Social.installProvider(doc, manifest2, function(addonManifest) {
+          // at this point, we should have a button id in the currentset for our provider
+          let id = "social-status-button-" + manifest2.origin;
+          let toolbar = document.getElementById("nav-bar");
+
+          waitForCondition(function() {
+                             let currentset = toolbar.getAttribute("currentset").split(',');
+                             return currentset.indexOf(id) >= 0;
+                           },
+                           function() {
+                             // no longer need the tab
+                             gBrowser.removeTab(tab);
+                             next();
+                           }, "status button added to currentset");
+      });
+    });
+  },
+  testButtonOnEnable: function(next) {
+    // enable the provider now
+    SocialService.addBuiltinProvider(manifest2.origin, function(provider) {
+      ok(provider, "provider is installed");
+      let id = "social-status-button-" + manifest2.origin;
+      waitForCondition(function() { return document.getElementById(id) },
+                       next, "button exists after enabling social");
+    });
+  },
+  testStatusPanel: function(next) {
+    let icon = {
+      name: "testIcon",
+      iconURL: "chrome://browser/skin/Info.png",
+      counter: 1
+    };
+    // click on panel to open and wait for visibility
+    let provider = Social._getProviderFromOrigin(manifest2.origin);
+    let id = "social-status-button-" + provider.origin;
+    let btn = document.getElementById(id)
+    ok(btn, "got a status button");
+    let port = provider.getWorkerPort();
+
+    port.onmessage = function (e) {
+      let topic = e.data.topic;
+      switch (topic) {
+        case "test-init-done":
+          ok(true, "test-init-done received");
+          ok(provider.profile.userName, "profile was set by test worker");
+          btn.click();
+          break;
+        case "got-social-panel-visibility":
+          ok(true, "got the panel message " + e.data.result);
+          if (e.data.result == "shown") {
+            let panel = document.getElementById("social-notification-panel");
+            panel.hidePopup();
+          } else {
+            port.postMessage({topic: "test-ambient-notification", data: icon});
+            port.close();
+            waitForCondition(function() { return btn.getAttribute("badge"); },
+                       function() {
+                         is(btn.style.listStyleImage, "url(\"" + icon.iconURL + "\")", "notification icon updated");
+                         next();
+                       }, "button updated by notification");
+          }
+          break;
+      }
+    };
+    port.postMessage({topic: "test-init"});
+  },
+  testButtonOnDisable: function(next) {
+    // enable the provider now
+    let provider = Social._getProviderFromOrigin(manifest2.origin);
+    ok(provider, "provider is installed");
+    SocialService.removeProvider(manifest2.origin, function() {
+      let id = "social-status-button-" + manifest2.origin;
+      waitForCondition(function() { return !document.getElementById(id) },
+                       next, "button does not exist after disabling the provider");
+    });
+  },
+  testButtonOnUninstall: function(next) {
+    Social.uninstallProvider(manifest2.origin, function() {
+      // test that the button is no longer persisted
+      let id = "social-status-button-" + manifest2.origin;
+      let toolbar = document.getElementById("nav-bar");
+      let currentset = toolbar.getAttribute("currentset").split(',');
+      is(currentset.indexOf(id), -1, "button no longer in currentset");
+      next();
+    });
+  }
+}
--- a/browser/base/content/test/social/head.js
+++ b/browser/base/content/test/social/head.js
@@ -172,17 +172,17 @@ function runSocialTests(tests, cbPreTest
     // We run on a timeout as the frameworker also makes use of timeouts, so
     // this helps keep the debug messages sane.
     executeSoon(function() {
       function cleanupAndRunNextTest() {
         info("sub-test " + name + " complete");
         cbPostTest(runNextTest);
       }
       cbPreTest(function() {
-        is(providersAtStart, Social.providers.length, "pre-test: no new providers left enabled");
+        info("pre-test: starting with " + Social.providers.length + " providers");
         info("sub-test " + name + " starting");
         try {
           func.call(tests, cleanupAndRunNextTest);
         } catch (ex) {
           ok(false, "sub-test " + name + " failed: " + ex.toString() +"\n"+ex.stack);
           cleanupAndRunNextTest();
         }
       })
--- a/browser/base/content/test/social/social_activate.html
+++ b/browser/base/content/test/social/social_activate.html
@@ -9,16 +9,17 @@ var data = {
   "name": "Demo Social Service",
   "iconURL": "chrome://branding/content/icon16.png",
   "icon32URL": "chrome://branding/content/favicon32.png",
   "icon64URL": "chrome://branding/content/icon64.png",
 
   // at least one of these must be defined
   "sidebarURL": "/browser/browser/base/content/test/social/social_sidebar.html",
   "workerURL": "/browser/browser/base/content/test/social/social_worker.js",
+  "statusURL": "/browser/browser/base/content/test/social/social_panel.html",
 
   // should be available for display purposes
   "description": "A short paragraph about this provider",
   "author": "Shane Caraveo, Mozilla",
 
   // optional
   "version": 1
 }
--- a/browser/base/content/test/social/social_worker.js
+++ b/browser/base/content/test/social/social_worker.js
@@ -114,23 +114,17 @@ onconnect = function(e) {
               markedTooltip: "Unmark this page",
               unmarkedLabel: "Mark",
               markedLabel: "Unmark",
             }
           }
         });
         break;
       case "test-ambient-notification":
-        let icon = {
-          name: "testIcon",
-          iconURL: "chrome://browser/skin/Info.png",
-          contentPanel: "https://example.com/browser/browser/base/content/test/social/social_panel.html",
-          counter: 1
-        };
-        apiPort.postMessage({topic: "social.ambient-notification", data: icon});
+        apiPort.postMessage({topic: "social.ambient-notification", data: event.data.data});
         break;
       case "test-isVisible":
         sidebarPort.postMessage({topic: "test-isVisible"});
         break;
       case "test-isVisible-response":
         testPort.postMessage({topic: "got-isVisible-response", result: event.data.result});
         break;
       case "share-data-message":
--- a/browser/components/nsBrowserGlue.js
+++ b/browser/components/nsBrowserGlue.js
@@ -1729,25 +1729,21 @@ BrowserGlue.prototype = {
 function ContentPermissionPrompt() {}
 
 ContentPermissionPrompt.prototype = {
   classID:          Components.ID("{d8903bf6-68d5-4e97-bcd1-e4d3012f721a}"),
 
   QueryInterface: XPCOMUtils.generateQI([Ci.nsIContentPermissionPrompt]),
 
   _getBrowserForRequest: function (aRequest) {
-    var browser;
-    try {
-      // "element" is only defined in e10s mode, otherwise it throws.
-      browser = aRequest.element;
-    } catch (e) {}
+    // "element" is only defined in e10s mode.
+    let browser = aRequest.element;
     if (!browser) {
-      var requestingWindow = aRequest.window.top;
-      // find the requesting browser or iframe
-      browser = requestingWindow.QueryInterface(Ci.nsIInterfaceRequestor)
+      // Find the requesting browser.
+      browser = aRequest.window.QueryInterface(Ci.nsIInterfaceRequestor)
                                   .getInterface(Ci.nsIWebNavigation)
                                   .QueryInterface(Ci.nsIDocShell)
                                   .chromeEventHandler;
     }
     return browser;
   },
 
   /**
--- a/browser/devtools/scratchpad/scratchpad.js
+++ b/browser/devtools/scratchpad/scratchpad.js
@@ -15,27 +15,30 @@
 "use strict";
 
 let require = Components.utils.import("resource://gre/modules/devtools/Loader.jsm", {}).devtools.require;
 
 let { Cc, Ci, Cu } = require("chrome");
 let promise = require("sdk/core/promise");
 let Telemetry = require("devtools/shared/telemetry");
 let TargetFactory = require("devtools/framework/target").TargetFactory;
+const escodegen = require("escodegen/escodegen");
 
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 Cu.import("resource://gre/modules/Services.jsm");
 Cu.import("resource://gre/modules/NetUtil.jsm");
 Cu.import("resource:///modules/source-editor.jsm");
 Cu.import("resource:///modules/devtools/LayoutHelpers.jsm");
 Cu.import("resource:///modules/devtools/scratchpad-manager.jsm");
 Cu.import("resource://gre/modules/jsdebugger.jsm");
 Cu.import("resource:///modules/devtools/gDevTools.jsm");
 Cu.import("resource://gre/modules/osfile.jsm");
 Cu.import("resource:///modules/devtools/ViewHelpers.jsm");
+Cu.import("resource://gre/modules/reflect.jsm");
+Cu.import("resource://gre/modules/devtools/DevToolsUtils.jsm");
 
 XPCOMUtils.defineLazyModuleGetter(this, "VariablesView",
   "resource:///modules/devtools/VariablesView.jsm");
 
 XPCOMUtils.defineLazyModuleGetter(this, "VariablesViewController",
   "resource:///modules/devtools/VariablesViewController.jsm");
 
 XPCOMUtils.defineLazyModuleGetter(this, "ObjectClient",
@@ -517,16 +520,30 @@ var Scratchpad = {
         });
       }
     }, reject);
 
     return deferred.promise;
   },
 
   /**
+   * Pretty print the source text inside the scratchpad.
+   */
+  prettyPrint: function SP_prettyPrint() {
+    const uglyText = this.getText();
+    try {
+      const ast = Reflect.parse(uglyText);
+      const prettyText = escodegen.generate(ast);
+      this.setText(prettyText);
+    } catch (e) {
+      this.writeAsErrorComment(DevToolsUtils.safeErrorString(e));
+    }
+  },
+
+  /**
    * Writes out a primitive value as a comment. This handles values which are
    * to be printed directly (number, string) as well as grips to values
    * (null, undefined, longString).
    *
    * @param any aValue
    *        The value to print.
    * @return Promise
    *         The promise that resolves after the value has been printed.
--- a/browser/devtools/scratchpad/scratchpad.xul
+++ b/browser/devtools/scratchpad/scratchpad.xul
@@ -41,16 +41,17 @@
   <!-- TODO: bug 650340 - implement printFile()
   <command id="sp-cmd-printFile" oncommand="Scratchpad.printFile();" disabled="true"/>
  -->
 
   <command id="sp-cmd-close" oncommand="Scratchpad.close();"/>
   <command id="sp-cmd-run" oncommand="Scratchpad.run();"/>
   <command id="sp-cmd-inspect" oncommand="Scratchpad.inspect();"/>
   <command id="sp-cmd-display" oncommand="Scratchpad.display();"/>
+  <command id="sp-cmd-pprint" oncommand="Scratchpad.prettyPrint();"/>
   <command id="sp-cmd-contentContext" oncommand="Scratchpad.setContentContext();"/>
   <command id="sp-cmd-browserContext" oncommand="Scratchpad.setBrowserContext();" disabled="true"/>
   <command id="sp-cmd-reloadAndRun" oncommand="Scratchpad.reloadAndRun();"/>
   <command id="sp-cmd-errorConsole" oncommand="Scratchpad.openErrorConsole();" disabled="true"/>
   <command id="sp-cmd-webConsole" oncommand="Scratchpad.openWebConsole();"/>
   <command id="sp-cmd-documentationLink" oncommand="Scratchpad.openDocumentationPage();"/>
   <command id="sp-cmd-hideSidebar" oncommand="Scratchpad.sidebar.hide();"/>
 </commandset>
@@ -89,16 +90,20 @@
   <key id="sp-key-inspect"
        key="&inspect.key;"
        command="sp-cmd-inspect"
        modifiers="accel"/>
   <key id="sp-key-display"
        key="&display.key;"
        command="sp-cmd-display"
        modifiers="accel"/>
+  <key id="sp-key-pprint"
+       key="&pprint.key;"
+       command="sp-cmd-pprint"
+       modifiers="accel"/>
   <key id="sp-key-reloadAndRun"
        key="&reloadAndRun.key;"
        command="sp-cmd-reloadAndRun"
        modifiers="accel,shift"/>
   <key id="sp-key-errorConsole"
        key="&errorConsoleCmd.commandkey;"
        command="sp-cmd-errorConsole"
        modifiers="accel,shift"/>
@@ -267,16 +272,21 @@
   <toolbarbutton id="sp-toolbar-inspect"
                  class="devtools-toolbarbutton"
                  label="&inspect.label;"
                  command="sp-cmd-inspect"/>
   <toolbarbutton id="sp-toolbar-display"
                  class="devtools-toolbarbutton"
                  label="&display.label;"
                  command="sp-cmd-display"/>
+  <toolbarspacer/>
+  <toolbarbutton id="sp-toolbar-pprint"
+                 class="devtools-toolbarbutton"
+                 label="&pprint.label;"
+                 command="sp-cmd-pprint"/>
 </toolbar>
 
 
 <popupset id="scratchpad-popups">
   <menupopup id="scratchpad-text-popup"
              onpopupshowing="goUpdateSourceEditorMenuItems()">
     <menuitem id="se-cMenu-cut"/>
     <menuitem id="se-cMenu-copy"/>
--- a/browser/devtools/scratchpad/test/Makefile.in
+++ b/browser/devtools/scratchpad/test/Makefile.in
@@ -34,14 +34,15 @@ MOCHITEST_BROWSER_FILES = \
 		browser_scratchpad_bug756681_display_non_error_exceptions.js \
 		browser_scratchpad_bug_751744_revert_to_saved.js \
 		browser_scratchpad_bug740948_reload_and_run.js \
 		browser_scratchpad_bug_661762_wrong_window_focus.js \
 		browser_scratchpad_bug_644413_modeline.js \
 		browser_scratchpad_bug807924_cannot_convert_to_string.js \
 		browser_scratchpad_long_string.js \
 		browser_scratchpad_open_error_console.js \
+		browser_scratchpad_pprint.js \
 		head.js \
 
 # Disable test due to bug 807234 becoming basically permanent
 #		browser_scratchpad_bug_653427_confirm_close.js \
 
 include $(topsrcdir)/config/rules.mk
new file mode 100644
--- /dev/null
+++ b/browser/devtools/scratchpad/test/browser_scratchpad_pprint.js
@@ -0,0 +1,26 @@
+/* vim: set ts=2 et sw=2 tw=80: */
+/* Any copyright is dedicated to the Public Domain.
+   http://creativecommons.org/publicdomain/zero/1.0/ */
+
+function test()
+{
+  waitForExplicitFinish();
+
+  gBrowser.selectedTab = gBrowser.addTab();
+  gBrowser.selectedBrowser.addEventListener("load", function onLoad() {
+    gBrowser.selectedBrowser.removeEventListener("load", onLoad, true);
+    openScratchpad(runTests);
+  }, true);
+
+  content.location = "data:text/html;charset=utf8,test Scratchpad pretty print.";
+}
+
+function runTests(sw)
+{
+  const sp = sw.Scratchpad;
+  sp.setText("function main() { console.log(5); }");
+  sp.prettyPrint();
+  const prettyText = sp.getText();
+  ok(prettyText.contains("\n"));
+  finish();
+}
--- a/browser/devtools/styleinspector/rule-view.js
+++ b/browser/devtools/styleinspector/rule-view.js
@@ -6,17 +6,17 @@
 
 "use strict";
 
 const {Cc, Ci, Cu} = require("chrome");
 const promise = require("sdk/core/promise");
 
 let {CssLogic} = require("devtools/styleinspector/css-logic");
 let {InplaceEditor, editableField, editableItem} = require("devtools/shared/inplace-editor");
-let {ELEMENT_STYLE} = require("devtools/server/actors/styles");
+let {ELEMENT_STYLE, PSEUDO_ELEMENTS} = require("devtools/server/actors/styles");
 
 Cu.import("resource://gre/modules/Services.jsm");
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 
 const HTML_NS = "http://www.w3.org/1999/xhtml";
 const XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
 
 /**
@@ -198,29 +198,41 @@ ElementStyle.prototype = {
 
         this.rules = [];
 
         for (let entry of entries) {
           this._maybeAddRule(entry);
         }
 
         // Mark overridden computed styles.
-        this.markOverridden();
+        this.markOverriddenAll();
+
+        this._sortRulesForPseudoElement();
 
         // We're done with the previous list of rules.
         delete this._refreshRules;
 
         return null;
       });
     }).then(null, promiseWarn);
     this.populated = populated;
     return this.populated;
   },
 
   /**
+   * Put pseudo elements in front of others.
+   */
+   _sortRulesForPseudoElement: function ElementStyle_sortRulesForPseudoElement()
+   {
+      this.rules = this.rules.sort((a, b) => {
+        return (a.pseudoElement || "z") > (b.pseudoElement || "z");
+      });
+   },
+
+  /**
    * Add a rule if it's one we care about.  Filters out duplicates and
    * inherited styles with no inherited properties.
    *
    * @param {object} aOptions
    *        Options for creating the Rule, see the Rule constructor.
    *
    * @return {bool} true if we added the rule.
    */
@@ -261,32 +273,48 @@ ElementStyle.prototype = {
       return false;
     }
 
     this.rules.push(rule);
     return true;
   },
 
   /**
-   * Mark the properties listed in this.rules with an overridden flag
-   * if an earlier property overrides it.
+   * Calls markOverridden with all supported pseudo elements
    */
-  markOverridden: function ElementStyle_markOverridden()
+  markOverriddenAll: function ElementStyle_markOverriddenAll()
+  {
+    this.markOverridden();
+    for (let pseudo of PSEUDO_ELEMENTS) {
+      this.markOverridden(pseudo);
+    }
+  },
+
+  /**
+   * Mark the properties listed in this.rules for a given pseudo element
+   * with an overridden flag if an earlier property overrides it.
+   * @param {string} pseudo
+   *        Which pseudo element to flag as overridden.
+   *        Empty string or undefined will default to no pseudo element.
+   */
+  markOverridden: function ElementStyle_markOverridden(pseudo="")
   {
     // Gather all the text properties applied by these rules, ordered
     // from more- to less-specific.
     let textProps = [];
-    for each (let rule in this.rules) {
-      textProps = textProps.concat(rule.textProps.slice(0).reverse());
+    for (let rule of this.rules) {
+      if (rule.pseudoElement == pseudo) {
+        textProps = textProps.concat(rule.textProps.slice(0).reverse());
+      }
     }
 
     // Gather all the computed properties applied by those text
     // properties.
     let computedProps = [];
-    for each (let textProp in textProps) {
+    for (let textProp of textProps) {
       computedProps = computedProps.concat(textProp.computed);
     }
 
     // Walk over the computed properties.  As we see a property name
     // for the first time, mark that property's name as taken by this
     // property.
     //
     // If we come across a property whose name is already taken, check
@@ -297,17 +325,17 @@ ElementStyle.prototype = {
     //   the new property.
     //
     //   If the new property is a lower or equal priority, mark it as
     //   overridden.
     //
     // _overriddenDirty will be set on each prop, indicating whether its
     // dirty status changed during this pass.
     let taken = {};
-    for each (let computedProp in computedProps) {
+    for (let computedProp of computedProps) {
       let earlier = taken[computedProp.name];
       let overridden;
       if (earlier
           && computedProp.priority === "important"
           && earlier.priority !== "important") {
         // New property is higher priority.  Mark the earlier property
         // overridden (which will reverse its dirty state).
         earlier._overriddenDirty = !earlier._overriddenDirty;
@@ -323,17 +351,17 @@ ElementStyle.prototype = {
         taken[computedProp.name] = computedProp;
       }
     }
 
     // For each TextProperty, mark it overridden if all of its
     // computed properties are marked overridden.  Update the text
     // property's associated editor, if any.  This will clear the
     // _overriddenDirty state on all computed properties.
-    for each (let textProp in textProps) {
+    for (let textProp of textProps) {
       // _updatePropertyOverridden will return true if the
       // overridden state has changed for the text property.
       if (this._updatePropertyOverridden(textProp)) {
         textProp.updateEditor();
       }
     }
   },
 
@@ -379,16 +407,17 @@ ElementStyle.prototype = {
  * @constructor
  */
 function Rule(aElementStyle, aOptions)
 {
   this.elementStyle = aElementStyle;
   this.domRule = aOptions.rule || null;
   this.style = aOptions.rule;
   this.matchedSelectors = aOptions.matchedSelectors || [];
+  this.pseudoElement = aOptions.pseudoElement || "";
 
   this.inherited = aOptions.inherited || null;
   this._modificationDepth = 0;
 
   if (this.domRule) {
     let parentRule = this.domRule.parentRule;
     if (parentRule && parentRule.type == Ci.nsIDOMCSSRule.MEDIA_RULE) {
       this.mediaText = parentRule.mediaText;
@@ -553,17 +582,17 @@ Rule.prototype = {
             this.style, textProp.name,
             null,
             cssProp.value,
             textProp.value);
         }
         textProp.priority = cssProp.priority;
       }
 
-      this.elementStyle.markOverridden();
+      this.elementStyle.markOverriddenAll();
 
       if (promise === this._applyingModifications) {
         this._applyingModifications = null;
       }
 
       this.elementStyle._changed();
     }).then(null, promiseWarn);
     this._applyingModifications = promise;
@@ -637,17 +666,16 @@ Rule.prototype = {
   },
 
   _parseCSSText: function Rule_parseProperties(aCssText)
   {
     let lines = aCssText.match(CSS_LINE_RE);
     let props = [];
 
     for (let line of lines) {
-      dump("line: " + line + "\n");
       let [, name, value, priority] = CSS_PROP_RE.exec(line) || []
       if (!name || !value) {
         continue;
       }
 
       props.push({
         name: name,
         value: value,
@@ -1073,16 +1101,17 @@ CssRuleView.prototype = {
   _populate: function() {
     let elementStyle = this._elementStyle;
     return this._elementStyle.populate().then(() => {
       if (this._elementStyle != elementStyle) {
         return promise.reject("element changed");
       }
       this._createEditors();
 
+
       // Notify anyone that cares that we refreshed.
       var evt = this.doc.createEvent("Events");
       evt.initEvent("CssRuleViewRefreshed", true, false);
       this.element.dispatchEvent(evt);
       return undefined;
     }).then(null, promiseWarn);
   },
 
@@ -1128,43 +1157,128 @@ CssRuleView.prototype = {
   _changed: function CssRuleView_changed()
   {
     var evt = this.doc.createEvent("Events");
     evt.initEvent("CssRuleViewChanged", true, false);
     this.element.dispatchEvent(evt);
   },
 
   /**
+   * Text for header that shows above rules for this element
+   */
+  get selectedElementLabel ()
+  {
+    if (this._selectedElementLabel) {
+      return this._selectedElementLabel;
+    }
+    this._selectedElementLabel = CssLogic.l10n("rule.selectedElement");
+    return this._selectedElementLabel;
+  },
+
+  /**
+   * Text for header that shows above rules for pseudo elements
+   */
+  get pseudoElementLabel ()
+  {
+    if (this._pseudoElementLabel) {
+      return this._pseudoElementLabel;
+    }
+    this._pseudoElementLabel = CssLogic.l10n("rule.pseudoElement");
+    return this._pseudoElementLabel;
+  },
+
+  togglePseudoElementVisibility: function(value)
+  {
+    this._showPseudoElements = !!value;
+    let isOpen = this.showPseudoElements;
+
+    Services.prefs.setBoolPref("devtools.inspector.show_pseudo_elements",
+      isOpen);
+
+    this.element.classList.toggle("show-pseudo-elements", isOpen);
+
+    if (this.pseudoElementTwisty) {
+      if (isOpen) {
+        this.pseudoElementTwisty.setAttribute("open", "true");
+      }
+      else {
+        this.pseudoElementTwisty.removeAttribute("open");
+      }
+    }
+  },
+
+  get showPseudoElements ()
+  {
+    if (this._showPseudoElements === undefined) {
+      this._showPseudoElements =
+        Services.prefs.getBoolPref("devtools.inspector.show_pseudo_elements");
+    }
+    return this._showPseudoElements;
+  },
+
+  /**
    * Creates editor UI for each of the rules in _elementStyle.
    */
   _createEditors: function CssRuleView_createEditors()
   {
     // Run through the current list of rules, attaching
     // their editors in order.  Create editors if needed.
     let lastInheritedSource = "";
+    let seenPseudoElement = false;
+    let seenNormalElement = false;
+
     for (let rule of this._elementStyle.rules) {
       if (rule.domRule.system) {
         continue;
       }
 
+      // Only print header for this element if there are pseudo elements
+      if (seenPseudoElement && !seenNormalElement && !rule.pseudoElement) {
+        seenNormalElement = true;
+        let div = this.doc.createElementNS(HTML_NS, "div");
+        div.className = "theme-gutter ruleview-header";
+        div.textContent = this.selectedElementLabel;
+        this.element.appendChild(div);
+      }
+
       let inheritedSource = rule.inheritedSource;
       if (inheritedSource != lastInheritedSource) {
-        let h2 = this.doc.createElementNS(HTML_NS, "div");
-        h2.className = "ruleview-rule-inheritance theme-gutter";
-        h2.textContent = inheritedSource;
+        let div = this.doc.createElementNS(HTML_NS, "div");
+        div.className = "theme-gutter ruleview-header";
+        div.textContent = inheritedSource;
         lastInheritedSource = inheritedSource;
-        this.element.appendChild(h2);
+        this.element.appendChild(div);
+      }
+
+      if (!seenPseudoElement && rule.pseudoElement) {
+        seenPseudoElement = true;
+
+        let div = this.doc.createElementNS(HTML_NS, "div");
+        div.className = "theme-gutter ruleview-header";
+        div.textContent = this.pseudoElementLabel;
+
+        let twisty = this.pseudoElementTwisty =
+          this.doc.createElementNS(HTML_NS, "span");
+        twisty.className = "ruleview-expander theme-twisty";
+        twisty.addEventListener("click", () => {
+          this.togglePseudoElementVisibility(!this.showPseudoElements);
+        }, false);
+
+        div.insertBefore(twisty, div.firstChild);
+        this.element.appendChild(div);
       }
 
       if (!rule.editor) {
         new RuleEditor(this, rule);
       }
 
       this.element.appendChild(rule.editor.element);
     }
+
+    this.togglePseudoElementVisibility(this.showPseudoElements);
   },
 
   /**
    * Copy selected text from the rule view.
    *
    * @param {Event} aEvent
    *        The event object.
    */
@@ -1222,16 +1336,19 @@ function RuleEditor(aRuleView, aRule)
 }
 
 RuleEditor.prototype = {
   _create: function RuleEditor_create()
   {
     this.element = this.doc.createElementNS(HTML_NS, "div");
     this.element.className = "ruleview-rule theme-separator";
     this.element._ruleEditor = this;
+    if (this.rule.pseudoElement) {
+      this.element.classList.add("ruleview-rule-pseudo-element");
+    }
 
     // Give a relative position for the inplace editor's measurement
     // span to be placed absolutely against.
     this.element.style.position = "relative";
 
     // Add the source link.
     let source = createChild(this.element, "div", {
       class: "ruleview-rule-source theme-link"
@@ -1353,22 +1470,25 @@ RuleEditor.prototype = {
    * Programatically add a new property to the rule.
    *
    * @param {string} aName
    *        Property name.
    * @param {string} aValue
    *        Property value.
    * @param {string} aPriority
    *        Property priority.
+   * @return {TextProperty}
+   *        The new property
    */
   addProperty: function RuleEditor_addProperty(aName, aValue, aPriority)
   {
     let prop = this.rule.createProperty(aName, aValue, aPriority);
     let editor = new TextPropertyEditor(this, prop);
     this.propertyList.appendChild(editor.element);
+    return prop;
   },
 
   /**
    * Create a text input for a property name.  If a non-empty property
    * name is given, we'll create a real TextProperty and add it to the
    * rule.
    */
   newProperty: function RuleEditor_newProperty()
--- a/browser/devtools/styleinspector/ruleview.css
+++ b/browser/devtools/styleinspector/ruleview.css
@@ -31,8 +31,26 @@
 .ruleview-propertycontainer a {
   cursor: pointer;
 }
 
 .ruleview-computedlist:not(.styleinspector-open),
 .ruleview-warning[hidden] {
   display: none;
 }
+
+.ruleview-rule-pseudo-element {
+  display: none;
+}
+
+.show-pseudo-elements .ruleview-rule-pseudo-element {
+  display: block;
+}
+
+.ruleview .ruleview-expander {
+  vertical-align: middle;
+}
+
+.ruleview-header {
+  vertical-align:middle;
+  height: 1.5em;
+  line-height: 1.5em;
+}
\ No newline at end of file
--- a/browser/devtools/styleinspector/test/Makefile.in
+++ b/browser/devtools/styleinspector/test/Makefile.in
@@ -38,16 +38,17 @@ MOCHITEST_BROWSER_FILES = \
   browser_computedview_734259_style_editor_link.js \
   browser_computedview_copy.js\
   browser_styleinspector_bug_677930_urls_clickable.js \
   browser_bug893965_css_property_completion_new_property.js \
   browser_bug893965_css_property_completion_existing_property.js \
   browser_bug894376_css_value_completion_new_property_value_pair.js \
   browser_bug894376_css_value_completion_existing_property_value_pair.js \
   browser_ruleview_bug_902966_revert_value_on_ESC.js \
+  browser_ruleview_pseudoelement.js \
   head.js \
   $(NULL)
 
 MOCHITEST_BROWSER_FILES += \
   browser_bug683672.html \
   browser_bug705707_is_content_stylesheet.html \
   browser_bug705707_is_content_stylesheet_imported.css \
   browser_bug705707_is_content_stylesheet_imported2.css \
@@ -55,11 +56,12 @@ MOCHITEST_BROWSER_FILES += \
   browser_bug705707_is_content_stylesheet_script.css \
   browser_bug705707_is_content_stylesheet.xul \
   browser_bug705707_is_content_stylesheet_xul.css \
   browser_bug722196_identify_media_queries.html \
   browser_styleinspector_bug_677930_urls_clickable.html \
   browser_styleinspector_bug_677930_urls_clickable \
   browser_styleinspector_bug_677930_urls_clickable/browser_styleinspector_bug_677930_urls_clickable.css \
   test-image.png \
+  browser_ruleview_pseudoelement.html \
   $(NULL)
 
 include $(topsrcdir)/config/rules.mk
new file mode 100644
--- /dev/null
+++ b/browser/devtools/styleinspector/test/browser_ruleview_pseudoelement.html
@@ -0,0 +1,115 @@
+<!-- Any copyright is dedicated to the Public Domain.
+     http://creativecommons.org/publicdomain/zero/1.0/ -->
+<html>
+  <head>
+    <style>
+
+body {
+    color: #333;
+}
+
+.box {
+    float:left;
+    width: 128px;
+    height: 128px;
+    background: #ddd;
+    padding: 32px;
+    margin: 32px;
+    position:relative;
+}
+
+* {
+    cursor: default;
+}
+
+nothing {
+    cursor: pointer;
+}
+
+p::-moz-selection {
+    color: white;
+    background: black;
+}
+p::selection {
+    color: white;
+    background: black;
+}
+
+p:first-line {
+   background: blue;
+}
+p:first-letter {
+  color: red;
+  font-size: 130%;
+}
+
+.box:before {
+    background: green;
+    content: " ";
+    position: absolute;
+    height:32px;
+    width:32px;
+}
+
+.box:after {
+    background: red;
+    content: " ";
+    position: absolute;
+    border-radius: 50%;
+    height:32px;
+    width:32px;
+    top: 50%;
+    left: 50%;
+    margin-top: -16px;
+    margin-left: -16px;
+}
+
+.topleft:before {
+    top:0;
+    left:0;
+}
+
+.topright:before {
+    top:0;
+    right:0;
+}
+
+.bottomright:before {
+    bottom:10px;
+    right:10px;
+    color: red;
+}
+
+.bottomright:before {
+    bottom:0;
+    right:0;
+}
+
+.bottomleft:before {
+    bottom:0;
+    left:0;
+}
+
+    </style>
+  </head>
+  <body>
+    <h1>ruleview pseudoelement($("test"));</h1>
+
+    <div id="topleft" class="box topleft">
+        <p>Top Left<br />Position</p>
+    </div>
+
+    <div id="topright" class="box topright">
+        <p>Top Right<br />Position</p>
+    </div>
+
+    <div id="bottomright" class="box bottomright">
+        <p>Bottom Right<br />Position</p>
+    </div>
+
+    <div id="bottomleft" class="box bottomleft">
+        <p>Bottom Left<br />Position</p>
+    </div>
+
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/browser/devtools/styleinspector/test/browser_ruleview_pseudoelement.js
@@ -0,0 +1,317 @@
+/* vim: set ts=2 et sw=2 tw=80: */
+/* Any copyright is dedicated to the Public Domain.
+   http://creativecommons.org/publicdomain/zero/1.0/ */
+
+let doc;
+let inspector;
+let view;
+
+const TEST_URI = "http://example.com/browser/browser/" +
+                 "devtools/styleinspector/test/" +
+                 "browser_ruleview_pseudoelement.html";
+
+function testPseudoElements(aInspector, aRuleView)
+{
+  inspector = aInspector;
+  view = aRuleView;
+
+  testTopLeft();
+}
+
+function testTopLeft()
+{
+  testNode(doc.querySelector("#topleft"), (element, elementStyle) => {
+    let elementRules = elementStyle.rules.filter((rule) => { return !rule.pseudoElement; });
+    let afterRules = elementStyle.rules.filter((rule) => { return rule.pseudoElement === ":after"; });
+    let beforeRules = elementStyle.rules.filter((rule) => { return rule.pseudoElement === ":before"; });
+    let firstLineRules = elementStyle.rules.filter((rule) => { return rule.pseudoElement === ":first-line"; });
+    let firstLetterRules = elementStyle.rules.filter((rule) => { return rule.pseudoElement === ":first-letter"; });
+    let selectionRules = elementStyle.rules.filter((rule) => { return rule.pseudoElement === ":-moz-selection"; });
+
+    is(elementRules.length, 4, "TopLeft has the correct number of non psuedo element rules");
+    is(afterRules.length, 1, "TopLeft has the correct number of :after rules");
+    is(beforeRules.length, 2, "TopLeft has the correct number of :before rules");
+    is(firstLineRules.length, 0, "TopLeft has the correct number of :first-line rules");
+    is(firstLetterRules.length, 0, "TopLeft has the correct number of :first-letter rules");
+    is(selectionRules.length, 0, "TopLeft has the correct number of :selection rules");
+
+    let gutters = view.element.querySelectorAll(".theme-gutter");
+    is (gutters.length, 3, "There are three gutter headings");
+    is (gutters[0].textContent, "Pseudo-elements", "Gutter heading is correct");
+    is (gutters[1].textContent, "This Element", "Gutter heading is correct");
+    is (gutters[2].textContent, "Inherited from body", "Gutter heading is correct");
+
+    // Make sure that clicking on the twisty hides pseudo elements
+    let expander = gutters[0].querySelector(".ruleview-expander");
+    ok (view.element.classList.contains("show-pseudo-elements"), "Pseudo Elements are expanded");
+    expander.click();
+    ok (!view.element.classList.contains("show-pseudo-elements"), "Pseudo Elements are collapsed by twisty");
+    expander.click();
+    ok (view.element.classList.contains("show-pseudo-elements"), "Pseudo Elements are expanded again");
+    expander.click();
+
+    let defaultView = element.ownerDocument.defaultView;
+    let elementRule = elementRules[0];
+    let elementRuleView = [].filter.call(view.element.children, (e) => {
+      return e._ruleEditor && e._ruleEditor.rule === elementRule;
+    })[0]._ruleEditor;
+
+    let elementAfterRule = afterRules[0];
+    let elementAfterRuleView = [].filter.call(view.element.children, (e) => {
+      return e._ruleEditor && e._ruleEditor.rule === elementAfterRule;
+    })[0]._ruleEditor;
+
+    is
+    (
+      convertTextPropsToString(elementAfterRule.textProps),
+      "background: none repeat scroll 0% 0% red; content: \" \"; position: absolute; " +
+      "border-radius: 50%; height: 32px; width: 32px; top: 50%; left: 50%; margin-top: -16px; margin-left: -16px",
+      "TopLeft after properties are correct"
+    );
+
+    let elementBeforeRule = beforeRules[0];
+    let elementBeforeRuleView = [].filter.call(view.element.children, (e) => {
+      return e._ruleEditor && e._ruleEditor.rule === elementBeforeRule;
+    })[0]._ruleEditor;
+
+    is
+    (
+      convertTextPropsToString(elementBeforeRule.textProps),
+      "top: 0px; left: 0px",
+      "TopLeft before properties are correct"
+    );
+
+    let firstProp = elementAfterRuleView.addProperty("background-color", "rgb(0, 255, 0)", "");
+    let secondProp = elementAfterRuleView.addProperty("padding", "100px", "");
+
+    is (firstProp, elementAfterRule.textProps[elementAfterRule.textProps.length - 2],
+        "First added property is on back of array");
+    is (secondProp, elementAfterRule.textProps[elementAfterRule.textProps.length - 1],
+        "Second added property is on back of array");
+
+    promiseDone(elementAfterRule._applyingModifications.then(() => {
+      is(defaultView.getComputedStyle(element, ":after").getPropertyValue("background-color"),
+        "rgb(0, 255, 0)", "Added property should have been used.");
+      is(defaultView.getComputedStyle(element, ":after").getPropertyValue("padding-top"),
+        "100px", "Added property should have been used.");
+      is(defaultView.getComputedStyle(element).getPropertyValue("padding-top"),
+        "32px", "Added property should not apply to element");
+
+      secondProp.setEnabled(false);
+
+      return elementAfterRule._applyingModifications;
+    }).then(() => {
+      is(defaultView.getComputedStyle(element, ":after").getPropertyValue("padding-top"), "0px",
+        "Disabled property should have been used.");
+      is(defaultView.getComputedStyle(element).getPropertyValue("padding-top"), "32px",
+        "Added property should not apply to element");
+
+      secondProp.setEnabled(true);
+
+      return elementAfterRule._applyingModifications;
+    }).then(() => {
+      is(defaultView.getComputedStyle(element, ":after").getPropertyValue("padding-top"), "100px",
+        "Enabled property should have been used.");
+      is(defaultView.getComputedStyle(element).getPropertyValue("padding-top"), "32px",
+        "Added property should not apply to element");
+
+      let firstProp = elementRuleView.addProperty("background-color", "rgb(0, 0, 255)", "");
+
+      return elementRule._applyingModifications;
+    }).then(() => {
+      is(defaultView.getComputedStyle(element).getPropertyValue("background-color"), "rgb(0, 0, 255)",
+        "Added property should have been used.");
+      is(defaultView.getComputedStyle(element, ":after").getPropertyValue("background-color"), "rgb(0, 255, 0)",
+        "Added prop does not apply to pseudo");
+
+      testTopRight();
+    }));
+  });
+}
+
+function testTopRight()
+{
+  testNode(doc.querySelector("#topright"), (element, elementStyle) => {
+
+    let elementRules = elementStyle.rules.filter((rule) => { return !rule.pseudoElement; });
+    let afterRules = elementStyle.rules.filter((rule) => { return rule.pseudoElement === ":after"; });
+    let beforeRules = elementStyle.rules.filter((rule) => { return rule.pseudoElement === ":before"; });
+    let firstLineRules = elementStyle.rules.filter((rule) => { return rule.pseudoElement === ":first-line"; });
+    let firstLetterRules = elementStyle.rules.filter((rule) => { return rule.pseudoElement === ":first-letter"; });
+    let selectionRules = elementStyle.rules.filter((rule) => { return rule.pseudoElement === ":-moz-selection"; });
+
+    is(elementRules.length, 4, "TopRight has the correct number of non psuedo element rules");
+    is(afterRules.length, 1, "TopRight has the correct number of :after rules");
+    is(beforeRules.length, 2, "TopRight has the correct number of :before rules");
+    is(firstLineRules.length, 0, "TopRight has the correct number of :first-line rules");
+    is(firstLetterRules.length, 0, "TopRight has the correct number of :first-letter rules");
+    is(selectionRules.length, 0, "TopRight has the correct number of :selection rules");
+
+    let gutters = view.element.querySelectorAll(".theme-gutter");
+    is (gutters.length, 3, "There are three gutter headings");
+    is (gutters[0].textContent, "Pseudo-elements", "Gutter heading is correct");
+    is (gutters[1].textContent, "This Element", "Gutter heading is correct");
+    is (gutters[2].textContent, "Inherited from body", "Gutter heading is correct");
+
+    let expander = gutters[0].querySelector(".ruleview-expander");
+    ok (!view.element.classList.contains("show-pseudo-elements"), "Pseudo Elements remain collapsed after switching element");
+    expander.scrollIntoView();
+    expander.click();
+    ok (view.element.classList.contains("show-pseudo-elements"), "Pseudo Elements are shown again after clicking twisty");
+
+    testBottomRight();
+  });
+}
+
+function testBottomRight()
+{
+  testNode(doc.querySelector("#bottomright"), (element, elementStyle) => {
+
+    let elementRules = elementStyle.rules.filter((rule) => { return !rule.pseudoElement; });
+    let afterRules = elementStyle.rules.filter((rule) => { return rule.pseudoElement === ":after"; });
+    let beforeRules = elementStyle.rules.filter((rule) => { return rule.pseudoElement === ":before"; });
+    let firstLineRules = elementStyle.rules.filter((rule) => { return rule.pseudoElement === ":first-line"; });
+    let firstLetterRules = elementStyle.rules.filter((rule) => { return rule.pseudoElement === ":first-letter"; });
+    let selectionRules = elementStyle.rules.filter((rule) => { return rule.pseudoElement === ":-moz-selection"; });
+
+    is(elementRules.length, 4, "BottomRight has the correct number of non psuedo element rules");
+    is(afterRules.length, 1, "BottomRight has the correct number of :after rules");
+    is(beforeRules.length, 3, "BottomRight has the correct number of :before rules");
+    is(firstLineRules.length, 0, "BottomRight has the correct number of :first-line rules");
+    is(firstLetterRules.length, 0, "BottomRight has the correct number of :first-letter rules");
+    is(selectionRules.length, 0, "BottomRight has the correct number of :selection rules");
+
+    testBottomLeft();
+  });
+}
+
+function testBottomLeft()
+{
+  testNode(doc.querySelector("#bottomleft"), (element, elementStyle) => {
+
+    let elementRules = elementStyle.rules.filter((rule) => { return !rule.pseudoElement; });
+    let afterRules = elementStyle.rules.filter((rule) => { return rule.pseudoElement === ":after"; });
+    let beforeRules = elementStyle.rules.filter((rule) => { return rule.pseudoElement === ":before"; });
+    let firstLineRules = elementStyle.rules.filter((rule) => { return rule.pseudoElement === ":first-line"; });
+    let firstLetterRules = elementStyle.rules.filter((rule) => { return rule.pseudoElement === ":first-letter"; });
+    let selectionRules = elementStyle.rules.filter((rule) => { return rule.pseudoElement === ":-moz-selection"; });
+
+    is(elementRules.length, 4, "BottomLeft has the correct number of non psuedo element rules");
+    is(afterRules.length, 1, "BottomLeft has the correct number of :after rules");
+    is(beforeRules.length, 2, "BottomLeft has the correct number of :before rules");
+    is(firstLineRules.length, 0, "BottomLeft has the correct number of :first-line rules");
+    is(firstLetterRules.length, 0, "BottomLeft has the correct number of :first-letter rules");
+    is(selectionRules.length, 0, "BottomLeft has the correct number of :selection rules");
+
+    testParagraph();
+  });
+}
+
+function testParagraph()
+{
+  testNode(doc.querySelector("#bottomleft p"), (element, elementStyle) => {
+
+    let elementRules = elementStyle.rules.filter((rule) => { return !rule.pseudoElement; });
+    let afterRules = elementStyle.rules.filter((rule) => { return rule.pseudoElement === ":after"; });
+    let beforeRules = elementStyle.rules.filter((rule) => { return rule.pseudoElement === ":before"; });
+    let firstLineRules = elementStyle.rules.filter((rule) => { return rule.pseudoElement === ":first-line"; });
+    let firstLetterRules = elementStyle.rules.filter((rule) => { return rule.pseudoElement === ":first-letter"; });
+    let selectionRules = elementStyle.rules.filter((rule) => { return rule.pseudoElement === ":-moz-selection"; });
+
+    is(elementRules.length, 3, "Paragraph has the correct number of non psuedo element rules");
+    is(afterRules.length, 0, "Paragraph has the correct number of :after rules");
+    is(beforeRules.length, 0, "Paragraph has the correct number of :before rules");
+    is(firstLineRules.length, 1, "Paragraph has the correct number of :first-line rules");
+    is(firstLetterRules.length, 1, "Paragraph has the correct number of :first-letter rules");
+    is(selectionRules.length, 1, "Paragraph has the correct number of :selection rules");
+
+    let gutters = view.element.querySelectorAll(".theme-gutter");
+    is (gutters.length, 3, "There are three gutter headings");
+    is (gutters[0].textContent, "Pseudo-elements", "Gutter heading is correct");
+    is (gutters[1].textContent, "This Element", "Gutter heading is correct");
+    is (gutters[2].textContent, "Inherited from body", "Gutter heading is correct");
+
+    let elementFirstLineRule = firstLineRules[0];
+    let elementFirstLineRuleView = [].filter.call(view.element.children, (e) => {
+      return e._ruleEditor && e._ruleEditor.rule === elementFirstLineRule;
+    })[0]._ruleEditor;
+
+    is
+    (
+      convertTextPropsToString(elementFirstLineRule.textProps),
+      "background: none repeat scroll 0% 0% blue",
+      "Paragraph first-line properties are correct"
+    );
+
+    let elementFirstLetterRule = firstLetterRules[0];
+    let elementFirstLetterRuleView = [].filter.call(view.element.children, (e) => {
+      return e._ruleEditor && e._ruleEditor.rule === elementFirstLetterRule;
+    })[0]._ruleEditor;
+
+    is
+    (
+      convertTextPropsToString(elementFirstLetterRule.textProps),
+      "color: red; font-size: 130%",
+      "Paragraph first-letter properties are correct"
+    );
+
+    let elementSelectionRule = selectionRules[0];
+    let elementSelectionRuleView = [].filter.call(view.element.children, (e) => {
+      return e._ruleEditor && e._ruleEditor.rule === elementSelectionRule;
+    })[0]._ruleEditor;
+
+    is
+    (
+      convertTextPropsToString(elementSelectionRule.textProps),
+      "color: white; background: none repeat scroll 0% 0% black",
+      "Paragraph first-letter properties are correct"
+    );
+
+    testBody();
+  });
+}
+
+function testBody() {
+
+  testNode(doc.querySelector("body"), (element, elementStyle) => {
+
+    let gutters = view.element.querySelectorAll(".theme-gutter");
+    is (gutters.length, 0, "There are no gutter headings");
+
+    finishTest();
+  });
+
+}
+function convertTextPropsToString(textProps) {
+  return textProps.map((t) => {
+    return t.name + ": " + t.value;
+  }).join("; ");
+}
+
+function testNode(node, cb)
+{
+  inspector.once("inspector-updated", () => {
+    cb(node, view._elementStyle)
+  });
+  inspector.selection.setNode(node);
+}
+
+function finishTest()
+{
+  doc = null;
+  gBrowser.removeCurrentTab();
+  finish();
+}
+
+function test()
+{
+  waitForExplicitFinish();
+  gBrowser.selectedTab = gBrowser.addTab();
+  gBrowser.selectedBrowser.addEventListener("load", function(evt) {
+    gBrowser.selectedBrowser.removeEventListener(evt.type, arguments.callee, true);
+    doc = content.document;
+    waitForFocus(() => openRuleView(testPseudoElements), content);
+  }, true);
+
+  content.location = TEST_URI;
+}
--- a/browser/locales/en-US/chrome/browser/devtools/scratchpad.dtd
+++ b/browser/locales/en-US/chrome/browser/devtools/scratchpad.dtd
@@ -60,16 +60,19 @@
 <!ENTITY inspect.label                "Inspect">
 <!ENTITY inspect.accesskey            "I">
 <!ENTITY inspect.key                  "i">
 
 <!ENTITY display.label                "Display">
 <!ENTITY display.accesskey            "D">
 <!ENTITY display.key                  "l">
 
+<!ENTITY pprint.label                 "Pretty Print">
+<!ENTITY pprint.key                   "p">
+
 <!-- LOCALIZATION NOTE (environmentMenu.label, accesskey): This menu item was
   -  renamed from "Context" to avoid confusion with the right-click context
   -  menu in the text area. It refers to the JavaScript Environment (or context)
   -  the user is evaluating against. I.e., Content (current tab) or Chrome
   -  (browser).
   -->
 <!ENTITY environmentMenu.label        "Environment">
 <!ENTITY environmentMenu.accesskey    "N">
--- a/browser/locales/en-US/chrome/browser/devtools/styleinspector.properties
+++ b/browser/locales/en-US/chrome/browser/devtools/styleinspector.properties
@@ -30,16 +30,24 @@ rule.sourceInline=inline
 rule.sourceElement=element
 
 # LOCALIZATION NOTE (rule.inheritedFrom): Shown for CSS rules
 # that were inherited from a parent node. Will be passed a node
 # identifier of the parent node.
 # e.g "Inherited from body#bodyID"
 rule.inheritedFrom=Inherited from %S
 
+# LOCALIZATION NOTE (rule.pseudoElement): Shown for CSS rules
+# pseudo element header
+rule.pseudoElement=Pseudo-elements
+
+# LOCALIZATION NOTE (rule.pseudoElement): Shown for CSS rules
+# pseudo element header
+rule.selectedElement=This Element
+
 # LOCALIZATION NOTE (helpLinkTitle): For each style property
 # the user can hover it and get a help link button which allows one to
 # quickly jump to the documentation from the Mozilla Developer Network site.
 # This is the link title shown in the hover tooltip.
 helpLinkTitle=Read the documentation for this property
 
 # LOCALIZATION NOTE (rule.warning.title): When an invalid property value is
 # entered into the rule view a warning icon is displayed. This text is used for
--- a/browser/metro/modules/CrossSlide.jsm
+++ b/browser/metro/modules/CrossSlide.jsm
@@ -37,42 +37,38 @@ let CrossSlidingStateNames = [
 // --------------------------------
 // module helpers
 //
 
 function isSelectable(aElement) {
   // placeholder logic
   return aElement.nodeName == 'richgriditem';
 }
-
 function withinCone(aLen, aHeight) {
   // check pt falls within 45deg either side of the cross axis
   return aLen > aHeight;
 }
+function getScrollAxisFromElement(aElement) {
+  // keeping it simple - just return apparent scroll axis for the document
+  let win = aElement.ownerDocument.defaultView;
+  let scrollX = win.scrollMaxX,
+      scrollY = win.scrollMaxY;
+  // determine scroll axis from scrollable content when possible
+  if (scrollX || scrollY)
+    return scrollX >= scrollY ? 'x' : 'y';
 
-function getScrollAxisFromElement(aElement) {
-  let elem = aElement,
-      win = elem.ownerDocument.defaultView;
-  let scrollX, scrollY;
-  for (; elem && 1==elem.nodeType; elem = elem.parentNode) {
-    let cs = win.getComputedStyle(elem);
-    scrollX = (cs.overflowX=='scroll' || cs.overflowX=='auto');
-    scrollY = (cs.overflowX=='scroll' || cs.overflowX=='auto');
-    if (scrollX || scrollY) {
-      break;
-    }
-  }
-  return scrollX ? 'x' : 'y';
+  // fall back to guessing at scroll axis from document aspect ratio
+  let docElem = aElement.ownerDocument.documentElement;
+  return  docElem.clientWidth >= docElem.clientHeight ?
+          'x' : 'y';
 }
-
 function pointFromTouchEvent(aEvent) {
   let touch = aEvent.touches[0];
   return { x: touch.clientX, y: touch.clientY };
 }
-
 // This damping function has these important properties:
 // f(0) = 0
 // f'(0) = 1
 // limit as x -> Infinity of f(x) = 1
 function damp(aX) {
   return 2 / (1 + Math.exp(-2 * aX)) - 1;
 }
 function speedbump(aDelta, aStart, aEnd) {
--- a/browser/modules/Social.jsm
+++ b/browser/modules/Social.jsm
@@ -164,34 +164,38 @@ this.Social = {
       // Retrieve the current set of providers, and set the current provider.
       SocialService.getOrderedProviderList(function (providers) {
         Social._updateProviderCache(providers);
         Social._updateWorkerState(true);
       });
     }
 
     // Register an observer for changes to the provider list
-    SocialService.registerProviderListener(function providerListener(topic, data) {
+    SocialService.registerProviderListener(function providerListener(topic, origin, providers) {
       // An engine change caused by adding/removing a provider should notify.
       // any providers we receive are enabled in the AddonsManager
-      if (topic == "provider-added" || topic == "provider-removed") {
-        Social._updateProviderCache(data);
+      if (topic == "provider-installed" || topic == "provider-uninstalled") {
+        // installed/uninstalled do not send the providers param
+        Services.obs.notifyObservers(null, "social:" + topic, origin);
+        return;
+      }
+      if (topic == "provider-enabled" || topic == "provider-disabled") {
+        Social._updateProviderCache(providers);
         Social._updateWorkerState(true);
         Services.obs.notifyObservers(null, "social:providers-changed", null);
+        Services.obs.notifyObservers(null, "social:" + topic, origin);
         return;
       }
       if (topic == "provider-update") {
         // a provider has self-updated its manifest, we need to update our cache
         // and reload the provider.
-        let provider = data;
-        SocialService.getOrderedProviderList(function(providers) {
-          Social._updateProviderCache(providers);
-          provider.reload();
-          Services.obs.notifyObservers(null, "social:providers-changed", null);
-        });
+        Social._updateProviderCache(providers);
+        let provider = Social._getProviderFromOrigin(origin);
+        provider.reload();
+        Services.obs.notifyObservers(null, "social:providers-changed", null);
       }
     });
   },
 
   _updateWorkerState: function(enable) {
     // ensure that our providers are all disabled, and enabled if we allow
     // multiple workers
     if (enable && !Social.allowMultipleWorkers)
@@ -254,16 +258,20 @@ this.Social = {
     for (let p of this.providers) {
       if (p.origin == origin) {
         return p;
       }
     }
     return null;
   },
 
+  getManifestByOrigin: function(origin) {
+    return SocialService.getManifestByOrigin(origin);
+  },
+
   installProvider: function(doc, data, installCallback) {
     SocialService.installProvider(doc, data, installCallback);
   },
 
   uninstallProvider: function(origin, aCallback) {
     SocialService.uninstallProvider(origin, aCallback);
   },
 
--- a/browser/themes/linux/devtools/ruleview.css
+++ b/browser/themes/linux/devtools/ruleview.css
@@ -9,17 +9,17 @@
 .ruleview-rule-source {
   -moz-padding-start: 5px;
   cursor: pointer;
   text-align: right;
   float: right;
   -moz-user-select: none;
 }
 
-.ruleview-rule-inheritance {
+.ruleview-header {
   border-top-width: 1px;
   border-bottom-width: 1px;
   border-top-style: solid;
   border-bottom-style: solid;
   padding: 1px 4px;
   margin-top: 4px;
   -moz-user-select: none;
 }
--- a/browser/themes/osx/devtools/ruleview.css
+++ b/browser/themes/osx/devtools/ruleview.css
@@ -9,26 +9,30 @@
 .ruleview-rule-source {
   -moz-padding-start: 5px;
   cursor: pointer;
   text-align: right;
   float: right;
   -moz-user-select: none;
 }
 
-.ruleview-rule-inheritance {
+.ruleview-header {
   border-top-width: 1px;
   border-bottom-width: 1px;
   border-top-style: solid;
   border-bottom-style: solid;
   padding: 1px 4px;
-  margin-top: 4px;
   -moz-user-select: none;
 }
 
+.ruleview-rule-pseudo-element {
+  padding-left:20px;
+  border-left: solid 10px;
+}
+
 .ruleview-rule-source:hover {
   text-decoration: underline;
 }
 
 .ruleview-rule,
 #noResults {
   padding: 2px 4px;
 }
--- a/browser/themes/windows/devtools/ruleview.css
+++ b/browser/themes/windows/devtools/ruleview.css
@@ -9,17 +9,17 @@
 .ruleview-rule-source {
   -moz-padding-start: 5px;
   cursor: pointer;
   text-align: right;
   float: right;
   -moz-user-select: none;
 }
 
-.ruleview-rule-inheritance {
+.ruleview-header {
   border-top-width: 1px;
   border-bottom-width: 1px;
   border-top-style: solid;
   border-bottom-style: solid;
   padding: 1px 4px;
   margin-top: 4px;
   -moz-user-select: none;
 }
--- a/caps/tests/mochitest/test_disallowInheritPrincipal.html
+++ b/caps/tests/mochitest/test_disallowInheritPrincipal.html
@@ -17,29 +17,28 @@ https://bugzilla.mozilla.org/show_bug.cg
 <pre id="test">
 <script type="application/javascript">
 
 /** Test for Bug 732413
     Passing DISALLOW_INHERIT_PRINCIPAL flag should be effective even if
     aPrincipal is the system principal.
  **/
 
-netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
-const nsIScriptSecurityManager = Components.interfaces.nsIScriptSecurityManager;
-var secMan = Components.classes["@mozilla.org/scriptsecuritymanager;1"]
+const nsIScriptSecurityManager = SpecialPowers.Ci.nsIScriptSecurityManager;
+var secMan = SpecialPowers.Cc["@mozilla.org/scriptsecuritymanager;1"]
                        .getService(nsIScriptSecurityManager);
 var sysPrincipal = secMan.getSystemPrincipal();
 isnot(sysPrincipal, undefined, "Should have a principal");
 isnot(sysPrincipal, null, "Should have a non-null principal");
 is(secMan.isSystemPrincipal(sysPrincipal), true,
    "Should have system principal here");
 
 
-var ioService = Components.classes["@mozilla.org/network/io-service;1"].
-                getService(Components.interfaces.nsIIOService);
+var ioService = SpecialPowers.Cc["@mozilla.org/network/io-service;1"].
+                getService(SpecialPowers.Ci.nsIIOService);
 var inheritingURI = ioService.newURI("javascript:1+1", null, null);
 
 // First try a normal call to checkLoadURIWithPrincipal
 try {
   secMan.checkLoadURIWithPrincipal(sysPrincipal, inheritingURI,
                                    nsIScriptSecurityManager.STANDARD);
   ok(true, "checkLoadURI allowed the load");
 } catch (e) {
--- a/content/base/public/nsContentUtils.h
+++ b/content/base/public/nsContentUtils.h
@@ -1585,16 +1585,17 @@ public:
    * @note this should be used for HTML5 origin determination.
    */
   static nsresult GetASCIIOrigin(nsIPrincipal* aPrincipal,
                                  nsCString& aOrigin);
   static nsresult GetASCIIOrigin(nsIURI* aURI, nsCString& aOrigin);
   static nsresult GetUTFOrigin(nsIPrincipal* aPrincipal,
                                nsString& aOrigin);
   static nsresult GetUTFOrigin(nsIURI* aURI, nsString& aOrigin);
+  static void GetUTFNonNullOrigin(nsIURI* aURI, nsString& aOrigin);
 
   /**
    * This method creates and dispatches "command" event, which implements
    * nsIDOMXULCommandEvent.
    * If aShell is not null, dispatching goes via
    * nsIPresShell::HandleDOMEventWithTarget.
    */
   static nsresult DispatchXULCommand(nsIContent* aTarget,
--- a/content/base/src/Link.cpp
+++ b/content/base/src/Link.cpp
@@ -142,50 +142,51 @@ Link::SetProtocol(const nsAString &aProt
   nsAString::const_iterator iter(start);
   (void)FindCharInReadable(':', iter, end);
   (void)uri->SetScheme(NS_ConvertUTF16toUTF8(Substring(start, iter)));
 
   SetHrefAttribute(uri);
 }
 
 void
+Link::SetPassword(const nsAString &aPassword)
+{
+  nsCOMPtr<nsIURI> uri(GetURIToMutate());
+  if (!uri) {
+    // Ignore failures to be compatible with NS4.
+    return;
+  }
+
+  uri->SetPassword(NS_ConvertUTF16toUTF8(aPassword));
+  SetHrefAttribute(uri);
+}
+
+void
+Link::SetUsername(const nsAString &aUsername)
+{
+  nsCOMPtr<nsIURI> uri(GetURIToMutate());
+  if (!uri) {
+    // Ignore failures to be compatible with NS4.
+    return;
+  }
+
+  uri->SetUsername(NS_ConvertUTF16toUTF8(aUsername));
+  SetHrefAttribute(uri);
+}
+
+void
 Link::SetHost(const nsAString &aHost)
 {
   nsCOMPtr<nsIURI> uri(GetURIToMutate());
   if (!uri) {
     // Ignore failures to be compatible with NS4.
     return;
   }
 
-  // We cannot simply call nsIURI::SetHost because that would treat the name as
-  // an IPv6 address (like http:://[server:443]/).  We also cannot call
-  // nsIURI::SetHostPort because that isn't implemented.  Sadfaces.
-
-  // First set the hostname.
-  nsAString::const_iterator start, end;
-  aHost.BeginReading(start);
-  aHost.EndReading(end);
-  nsAString::const_iterator iter(start);
-  (void)FindCharInReadable(':', iter, end);
-  NS_ConvertUTF16toUTF8 host(Substring(start, iter));
-  (void)uri->SetHost(host);
-
-  // Also set the port if needed.
-  if (iter != end) {
-    iter++;
-    if (iter != end) {
-      nsAutoString portStr(Substring(iter, end));
-      nsresult rv;
-      int32_t port = portStr.ToInteger(&rv);
-      if (NS_SUCCEEDED(rv)) {
-        (void)uri->SetPort(port);
-      }
-    }
-  };
-
+  (void)uri->SetHostPort(NS_ConvertUTF16toUTF8(aHost));
   SetHrefAttribute(uri);
   return;
 }
 
 void
 Link::SetHostname(const nsAString &aHostname)
 {
   nsCOMPtr<nsIURI> uri(GetURIToMutate());
@@ -255,32 +256,77 @@ Link::SetHash(const nsAString &aHash)
     return;
   }
 
   (void)uri->SetRef(NS_ConvertUTF16toUTF8(aHash));
   SetHrefAttribute(uri);
 }
 
 void
+Link::GetOrigin(nsAString &aOrigin)
+{
+  aOrigin.Truncate();
+
+  nsCOMPtr<nsIURI> uri(GetURI());
+  if (!uri) {
+    return;
+  }
+
+  nsString origin;
+  nsContentUtils::GetUTFNonNullOrigin(uri, origin);
+  aOrigin.Assign(origin);
+}
+
+void
 Link::GetProtocol(nsAString &_protocol)
 {
   nsCOMPtr<nsIURI> uri(GetURI());
   if (!uri) {
     _protocol.AssignLiteral("http");
   }
   else {
     nsAutoCString scheme;
     (void)uri->GetScheme(scheme);
     CopyASCIItoUTF16(scheme, _protocol);
   }
   _protocol.Append(PRUnichar(':'));
   return;
 }
 
 void
+Link::GetUsername(nsAString& aUsername)
+{
+  aUsername.Truncate();
+
+  nsCOMPtr<nsIURI> uri(GetURI());
+  if (!uri) {
+    return;
+  }
+
+  nsAutoCString username;
+  uri->GetUsername(username);
+  CopyASCIItoUTF16(username, aUsername);
+}
+
+void
+Link::GetPassword(nsAString &aPassword)
+{
+  aPassword.Truncate();
+
+  nsCOMPtr<nsIURI> uri(GetURI());
+  if (!uri) {
+    return;
+  }
+
+  nsAutoCString password;
+  uri->GetPassword(password);
+  CopyASCIItoUTF16(password, aPassword);
+}
+
+void
 Link::GetHost(nsAString &_host)
 {
   _host.Truncate();
 
   nsCOMPtr<nsIURI> uri(GetURI());
   if (!uri) {
     // Do not throw!  Not having a valid URI should result in an empty string.
     return;
--- a/content/base/src/Link.h
+++ b/content/base/src/Link.h
@@ -49,23 +49,28 @@ public:
   virtual nsIURI* GetURIExternal() const {
     return GetURI();
   }
 
   /**
    * Helper methods for modifying and obtaining parts of the URI of the Link.
    */
   void SetProtocol(const nsAString &aProtocol);
+  void SetUsername(const nsAString &aUsername);
+  void SetPassword(const nsAString &aPassword);
   void SetHost(const nsAString &aHost);
   void SetHostname(const nsAString &aHostname);
   void SetPathname(const nsAString &aPathname);
   void SetSearch(const nsAString &aSearch);
   void SetPort(const nsAString &aPort);
   void SetHash(const nsAString &aHash);
+  void GetOrigin(nsAString &aOrigin);
   void GetProtocol(nsAString &_protocol);
+  void GetUsername(nsAString &aUsername);
+  void GetPassword(nsAString &aPassword);
   void GetHost(nsAString &_host);
   void GetHostname(nsAString &_hostname);
   void GetPathname(nsAString &_pathname);
   void GetSearch(nsAString &_search);
   void GetPort(nsAString &_port);
   void GetHash(nsAString &_hash);
 
   /**
--- a/content/base/src/nsContentUtils.cpp
+++ b/content/base/src/nsContentUtils.cpp
@@ -5512,16 +5512,29 @@ nsContentUtils::GetUTFOrigin(nsIURI* aUR
   else {
     aOrigin.AssignLiteral("null");
   }
   
   return NS_OK;
 }
 
 /* static */
+void
+nsContentUtils::GetUTFNonNullOrigin(nsIURI* aURI, nsString& aOrigin)
+{
+  aOrigin.Truncate();
+
+  nsString origin;
+  nsresult rv = GetUTFOrigin(aURI, origin);
+  if (NS_SUCCEEDED(rv) && !origin.EqualsLiteral("null")) {
+    aOrigin.Assign(origin);
+  }
+}
+
+/* static */
 already_AddRefed<nsIDocument>
 nsContentUtils::GetDocumentFromScriptContext(nsIScriptContext *aScriptContext)
 {
   if (!aScriptContext)
     return nullptr;
 
   nsCOMPtr<nsIDOMWindow> window =
     do_QueryInterface(aScriptContext->GetGlobalObject());
--- a/content/base/src/nsDOMFile.cpp
+++ b/content/base/src/nsDOMFile.cpp
@@ -597,16 +597,19 @@ nsDOMFileFile::GetInternalStream(nsIInpu
     NS_NewLocalFileInputStream(aStream, mFile, -1, -1, sFileStreamFlags) :
     NS_NewPartialLocalFileInputStream(aStream, mFile, mStart, mLength,
                                       -1, -1, sFileStreamFlags);
 }
 
 void
 nsDOMFileFile::SetPath(const nsAString& aPath)
 {
+  MOZ_ASSERT(aPath.IsEmpty() ||
+             aPath[aPath.Length() - 1] == PRUnichar('/'),
+             "Path must end with a path separator");
   mPath = aPath;
 }
 
 ////////////////////////////////////////////////////////////////////////////
 // nsDOMMemoryFile implementation
 
 already_AddRefed<nsIDOMBlob>
 nsDOMMemoryFile::CreateSlice(uint64_t aStart, uint64_t aLength,
--- a/content/base/test/copypaste.js
+++ b/content/base/test/copypaste.js
@@ -18,38 +18,38 @@ function modifySelection(s) {
   window.setTimeout(function () {
       e.parentNode.removeChild(e);
       g.removeAllRanges();
       g.addRange(l);
   }, 0)
 }
 
 function getLoadContext() {
-  var Ci = SpecialPowers.wrap(Components).interfaces;
+  var Ci = SpecialPowers.Ci;
   return SpecialPowers.wrap(window).QueryInterface(Ci.nsIInterfaceRequestor)
                                    .getInterface(Ci.nsIWebNavigation)
                                    .QueryInterface(Ci.nsILoadContext);
 }
 
 function testCopyPaste (isXHTML) {
   netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
 
   var suppressUnicodeCheckIfHidden = !!isXHTML;
   var suppressHTMLCheck = !!isXHTML;
 
-  var webnav = window.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
-                     .getInterface(Components.interfaces.nsIWebNavigation)
+  var webnav = window.QueryInterface(SpecialPowers.Ci.nsIInterfaceRequestor)
+                     .getInterface(SpecialPowers.Ci.nsIWebNavigation)
 
-  var docShell = webnav.QueryInterface(Components.interfaces.nsIDocShell);
+  var docShell = webnav.QueryInterface(SpecialPowers.Ci.nsIDocShell);
 
   var documentViewer = docShell.contentViewer
-                               .QueryInterface(Components.interfaces.nsIContentViewerEdit);
+                               .QueryInterface(SpecialPowers.Ci.nsIContentViewerEdit);
 
-  var clipboard = Components.classes["@mozilla.org/widget/clipboard;1"]
-                            .getService(Components.interfaces.nsIClipboard);
+  var clipboard = SpecialPowers.Cc["@mozilla.org/widget/clipboard;1"]
+                            .getService(SpecialPowers.Ci.nsIClipboard);
 
   var textarea = SpecialPowers.wrap(document.getElementById('input'));
 
   function copySelectionToClipboard(suppressUnicodeCheck) {
     documentViewer.copySelection();
     if (!suppressUnicodeCheck)
       ok(clipboard.hasDataMatchingFlavors(["text/unicode"], 1,1), "check text/unicode");
     if (!suppressHTMLCheck)
@@ -78,31 +78,31 @@ function testCopyPaste (isXHTML) {
   }
   function copyChildrenToClipboard(id) {
     textarea.blur();
     clipboard.emptyClipboard(1);
     window.getSelection().selectAllChildren(document.getElementById(id));
     copySelectionToClipboard();
   }
   function getClipboardData(mime) {
-    var transferable = Components.classes['@mozilla.org/widget/transferable;1']
-                                 .createInstance(Components.interfaces.nsITransferable);
+    var transferable = SpecialPowers.Cc['@mozilla.org/widget/transferable;1']
+                                    .createInstance(SpecialPowers.Ci.nsITransferable);
     transferable.init(getLoadContext());
     transferable.addDataFlavor(mime);
     clipboard.getData(transferable, 1);
     var data = {};
     transferable.getTransferData(mime, data, {}) ;
     return data;
   }
   function testClipboardValue(mime, expected) {
     if (suppressHTMLCheck && mime == "text/html")
       return null;
     var data = getClipboardData(mime);
     is (data.value == null ? data.value :
-        data.value.QueryInterface(Components.interfaces.nsISupportsString).data,
+        data.value.QueryInterface(SpecialPowers.Ci.nsISupportsString).data,
       expected,
       mime + " value in the clipboard");
     return data.value;
   }
   function testPasteText(expected) {
     textarea.value="";
     textarea.focus();
     textarea.editor.paste(1);
@@ -252,17 +252,16 @@ if (false) {
   // ============ manipulating Selection in oncopy
 
   copyRangeToClipboard($("div11").childNodes[0],0, $("div11").childNodes[1],2);
   testClipboardValue("text/unicode", "Xdiv11");
   testClipboardValue("text/html", "<div><p>X<span>div</span>11</p></div>");
   setTimeout(function(){testSelectionToString("div11")},0);
 
   setTimeout(function(){
-    netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
     copyRangeToClipboard($("div12").childNodes[0],0, $("div12").childNodes[1],2);
     testClipboardValue("text/unicode", "Xdiv12");
     testClipboardValue("text/html", "<div><p>X<span>div</span>12</p></div>");
     setTimeout(function(){ 
       testSelectionToString("div12"); 
       setTimeout(SimpleTest.finish,0);
     },0);
   },0);
--- a/content/base/test/fileutils.js
+++ b/content/base/test/fileutils.js
@@ -129,37 +129,35 @@ function testHasRun() {
  //alert(testRanCounter);
  ++testRanCounter;
  if (testRanCounter == expectedTestCount) {
     SimpleTest.finish();
   }
 }
 
 function createFileWithData(fileData) {
-  netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
-  var dirSvc = Components.classes["@mozilla.org/file/directory_service;1"].getService(Components.interfaces.nsIProperties);
-  var testFile = dirSvc.get("ProfD", Components.interfaces.nsIFile);
+  var dirSvc = SpecialPowers.Cc["@mozilla.org/file/directory_service;1"].getService(SpecialPowers.Ci.nsIProperties);
+  var testFile = dirSvc.get("ProfD", SpecialPowers.Ci.nsIFile);
   testFile.append("fileAPItestfile2-" + fileNum);
   fileNum++;
-  var outStream = Components.classes["@mozilla.org/network/file-output-stream;1"].createInstance(Components.interfaces.nsIFileOutputStream);
+  var outStream = SpecialPowers.Cc["@mozilla.org/network/file-output-stream;1"].createInstance(SpecialPowers.Ci.nsIFileOutputStream);
   outStream.init(testFile, 0x02 | 0x08 | 0x20, // write, create, truncate
                  0666, 0);
   outStream.write(fileData, fileData.length);
   outStream.close();
 
   var fileList = document.getElementById('fileList');
-  fileList.value = testFile.path;
+  SpecialPowers.wrap(fileList).value = testFile.path;
 
   return fileList.files[0];
 }
 
 function gc() {
-  netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
-  window.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
-        .getInterface(Components.interfaces.nsIDOMWindowUtils)
+  window.QueryInterface(SpecialPowers.Ci.nsIInterfaceRequestor)
+        .getInterface(SpecialPowers.Ci.nsIDOMWindowUtils)
         .garbageCollect();
 }
 
 function checkMPSubmission(sub, expected) {
   function getPropCount(o) {
     var x, l = 0;
     for (x in o) ++l;
     return l;
--- a/content/base/test/test_XHRSendData.html
+++ b/content/base/test/test_XHRSendData.html
@@ -73,20 +73,20 @@ extensions.forEach(
 
       var fileList = document.getElementById('fileList');
       fileList.value = testFile.path;
       testDOMFiles.push(fileList.files[0]);
     }
 );
 
 function createFileWithDataExt(fileData, extension) {
-  var dirSvc = Components.classes["@mozilla.org/file/directory_service;1"].getService(Components.interfaces.nsIProperties);
-  var testFile = dirSvc.get("ProfD", Components.interfaces.nsIFile);
+  var dirSvc = SpecialPowers.Cc["@mozilla.org/file/directory_service;1"].getService(SpecialPowers.Ci.nsIProperties);
+  var testFile = dirSvc.get("ProfD", SpecialPowers.Ci.nsIFile);
   testFile.append("testfile" + extension);
-  var outStream = Components.classes["@mozilla.org/network/file-output-stream;1"].createInstance(Components.interfaces.nsIFileOutputStream);
+  var outStream = SpecialPowers.Cc["@mozilla.org/network/file-output-stream;1"].createInstance(SpecialPowers.Ci.nsIFileOutputStream);
   outStream.init(testFile, 0x02 | 0x08 | 0x20, 0666, 0);
   outStream.write(fileData, fileData.length);
   outStream.close();
 
   return testFile;
 }
 
 tests = [{ body: null,
--- a/content/base/test/test_bug270145.xhtml
+++ b/content/base/test/test_bug270145.xhtml
@@ -12,20 +12,19 @@ https://bugzilla.mozilla.org/show_bug.cg
 <p id="display"></p>
 <div id="content" >
 <p id="foo"><![CDATA[a text to copy]]></p>
 </div>
 <pre id="test">
 <script class="testbody" type="text/javascript">
 //<![CDATA[
 function testHtmlCopyEncoder () {
-  netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
-  const de = Components.interfaces.nsIDocumentEncoder;
-  var encoder = Components.classes["@mozilla.org/layout/htmlCopyEncoder;1"]
-                   .createInstance(Components.interfaces.nsIDocumentEncoder);
+  const de = SpecialPowers.Ci.nsIDocumentEncoder;
+  var encoder = SpecialPowers.Cc["@mozilla.org/layout/htmlCopyEncoder;1"]
+                   .createInstance(SpecialPowers.Ci.nsIDocumentEncoder);
   var out, expected;
   
   var node = document.getElementById('draggable');
 
   var select = window.getSelection();
   select.removeAllRanges();
 
   node = document.getElementById("foo").firstChild;
--- a/content/base/test/test_bug401662.html
+++ b/content/base/test/test_bug401662.html
@@ -19,19 +19,18 @@ https://bugzilla.mozilla.org/show_bug.cg
 <pre id="test">
 <script class="testbody" type="text/javascript">
 
 /** Test for Bug 401662 - don't serialize style elements in body into
     plaintext**/
 SimpleTest.waitForExplicitFinish();
 
 window.onload = function() {
-  netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
-  const Cc = Components.classes;
-  const Ci = Components.interfaces;
+  const Cc = SpecialPowers.Cc;
+  const Ci = SpecialPowers.Ci;
 
   var encoder = Cc["@mozilla.org/layout/documentEncoder;1?type=text/html"]
                    .createInstance(Ci.nsIDocumentEncoder);
 
   var doc = $("testframe").contentDocument;
 
   encoder.init(doc, "text/plain", encoder.OutputBodyOnly);
   encoder.setCharset("UTF-8");
--- a/content/base/test/test_bug403852.html
+++ b/content/base/test/test_bug403852.html
@@ -18,18 +18,18 @@ https://bugzilla.mozilla.org/show_bug.cg
 <div id="content" style="display: none">
 </div>
 
 <pre id="test">
 <script class="testbody" type="text/javascript">
 
 netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
 
-var dirSvc = Components.classes["@mozilla.org/file/directory_service;1"].getService(Components.interfaces.nsIProperties);
-var testFile = dirSvc.get("ProfD", Components.interfaces.nsIFile);
+var dirSvc = SpecialPowers.Cc["@mozilla.org/file/directory_service;1"].getService(SpecialPowers.Ci.nsIProperties);
+var testFile = dirSvc.get("ProfD", SpecialPowers.Ci.nsIFile);
 testFile.append("prefs.js");
 
 var fileList = document.getElementById('fileList');
 fileList.value = testFile.path;
 
 // Make sure the file is accessible with indexed notation
 var domFile = fileList.files[0];
 
--- a/content/base/test/test_bug417384.html
+++ b/content/base/test/test_bug417384.html
@@ -16,31 +16,29 @@ https://bugzilla.mozilla.org/show_bug.cg
 </div>
 <pre id="test">
 <script class="testbody" type="text/javascript">
 
 /** Test for Bug 417384 **/
 
 var expectedSerialization = "about:blank document";
 function testSerializer() {
-  netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
-
   var doc = document.getElementById('test_iframe').contentDocument;
   doc.body.textContent = expectedSerialization;
   var head1 = doc.createElement("head");
   doc.body.appendChild(head1);
   var span = doc.createElement("span");
   head1.appendChild(span);
   span.appendChild(doc.createTextNode("before inner head\n"));
   span.appendChild(doc.createElement("head"));
   span.appendChild(doc.createTextNode("\nafter inner head"));
 
   var encoder =
-    Components.classes["@mozilla.org/layout/documentEncoder;1?type=text/html"]
-      .createInstance(Components.interfaces.nsIDocumentEncoder);
+    SpecialPowers.Cc["@mozilla.org/layout/documentEncoder;1?type=text/html"]
+      .createInstance(SpecialPowers.Ci.nsIDocumentEncoder);
   encoder.init(doc, "text/plain", 0);
   encoder.setCharset("UTF-8");
   var out = encoder.encodeToString();
   ok(out == expectedSerialization, "Wrong serialization!");
 }
 
 SimpleTest.waitForExplicitFinish();
 addLoadEvent(testSerializer);
--- a/content/base/test/test_bug422403-2.xhtml
+++ b/content/base/test/test_bug422403-2.xhtml
@@ -18,42 +18,41 @@
 <script class="testbody" type="text/javascript">
 //<![CDATA[
 
 function loadFileContent(aFile, aCharset) {
     //if(aAsIso == undefined) aAsIso = false;
     if(aCharset == undefined)
         aCharset = 'UTF-8';
 
-    var baseUri = Components.classes['@mozilla.org/network/standard-url;1']
-                   .createInstance(Components.interfaces.nsIURI);
+    var baseUri = SpecialPowers.Cc['@mozilla.org/network/standard-url;1']
+                   .createInstance(SpecialPowers.Ci.nsIURI);
     baseUri.spec = window.location.href;
 
-    var ios = Components.classes['@mozilla.org/network/io-service;1']
-            .getService(Components.interfaces.nsIIOService);
+    var ios = SpecialPowers.Cc['@mozilla.org/network/io-service;1']
+            .getService(SpecialPowers.Ci.nsIIOService);
     var chann = ios.newChannel(aFile, aCharset, baseUri);
 
-    var cis = Components.interfaces.nsIConverterInputStream;
+    var cis = SpecialPowers.Ci.nsIConverterInputStream;
 
-    var inputStream = Components.classes["@mozilla.org/intl/converter-input-stream;1"]
+    var inputStream = SpecialPowers.Cc["@mozilla.org/intl/converter-input-stream;1"]
                        .createInstance(cis);
     inputStream.init(chann.open(), aCharset, 1024, cis.DEFAULT_REPLACEMENT_CHARACTER);
     var str = {}, content = '';
     while (inputStream.readString(4096, str) != 0) {
         content += str.value;
     }
     return content;
 }
 
 
 function testHtmlSerializer_1 () {
-  netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
-  const de = Components.interfaces.nsIDocumentEncoder
-  var encoder = Components.classes["@mozilla.org/layout/documentEncoder;1?type=application/xhtml+xml"]
-                   .createInstance(Components.interfaces.nsIDocumentEncoder);
+  const de = SpecialPowers.Ci.nsIDocumentEncoder
+  var encoder = SpecialPowers.Cc["@mozilla.org/layout/documentEncoder;1?type=application/xhtml+xml"]
+                   .createInstance(SpecialPowers.Ci.nsIDocumentEncoder);
 
   var doc = $("testframe").contentDocument;
   var out, expected;
 
   // in the following tests, we must use the OutputLFLineBreak flag, to avoid
   // to have the default line break of the platform in the result, so the test
   // can pass on all platform
 
--- a/content/base/test/test_bug424359-1.html
+++ b/content/base/test/test_bug424359-1.html
@@ -18,47 +18,46 @@
 <script class="testbody" type="text/javascript">
 
 
 function loadFileContent(aFile, aCharset) {
     //if(aAsIso == undefined) aAsIso = false;
     if(aCharset == undefined)
         aCharset = 'UTF-8';
 
-    var baseUri = Components.classes['@mozilla.org/network/standard-url;1']
-                   .createInstance(Components.interfaces.nsIURI);
+    var baseUri = SpecialPowers.Cc['@mozilla.org/network/standard-url;1']
+                   .createInstance(SpecialPowers.Ci.nsIURI);
     baseUri.spec = window.location.href;
 
-    var ios = Components.classes['@mozilla.org/network/io-service;1']
-            .getService(Components.interfaces.nsIIOService);
+    var ios = SpecialPowers.Cc['@mozilla.org/network/io-service;1']
+            .getService(SpecialPowers.Ci.nsIIOService);
     var chann = ios.newChannel(aFile, aCharset, baseUri);
 
-    var cis = Components.interfaces.nsIConverterInputStream;
+    var cis = SpecialPowers.Ci.nsIConverterInputStream;
 
-    var inputStream = Components.classes["@mozilla.org/intl/converter-input-stream;1"]
+    var inputStream = SpecialPowers.Cc["@mozilla.org/intl/converter-input-stream;1"]
                        .createInstance(cis);
     inputStream.init(chann.open(), aCharset, 1024, cis.DEFAULT_REPLACEMENT_CHARACTER);
     var str = {}, content = '';
     while (inputStream.readString(4096, str) != 0) {
         content += str.value;
     }
     return content;
 }
 
 function isRoughly(actual, expected, message) {
   return is(actual.replace("<!DOCTYPE HTML", "<!DOCTYPE html"), 
             expected, 
             message);
 }
 
 function testHtmlSerializer_1 () {
-  netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
-  const de = Components.interfaces.nsIDocumentEncoder
-  var encoder = Components.classes["@mozilla.org/layout/documentEncoder;1?type=text/html"]
-                   .createInstance(Components.interfaces.nsIDocumentEncoder);
+  const de = SpecialPowers.Ci.nsIDocumentEncoder;
+  var encoder = SpecialPowers.Cc["@mozilla.org/layout/documentEncoder;1?type=text/html"]
+                   .createInstance(SpecialPowers.Ci.nsIDocumentEncoder);
 
   var doc = $("testframe").contentDocument;
   var out, expected;
 
   // in the following tests, we must use the OutputLFLineBreak flag, to avoid
   // to have the default line break of the platform in the result, so the test
   // can pass on all platform
 
--- a/content/base/test/test_bug424359-2.html
+++ b/content/base/test/test_bug424359-2.html
@@ -18,47 +18,46 @@
 <script class="testbody" type="text/javascript">
 
 
 function loadFileContent(aFile, aCharset) {
     //if(aAsIso == undefined) aAsIso = false;
     if(aCharset == undefined)
         aCharset = 'UTF-8';
 
-    var baseUri = Components.classes['@mozilla.org/network/standard-url;1']
-                   .createInstance(Components.interfaces.nsIURI);
+    var baseUri = SpecialPowers.Cc['@mozilla.org/network/standard-url;1']
+                   .createInstance(SpecialPowers.Ci.nsIURI);
     baseUri.spec = window.location.href;
 
-    var ios = Components.classes['@mozilla.org/network/io-service;1']
-            .getService(Components.interfaces.nsIIOService);
+    var ios = SpecialPowers.Cc['@mozilla.org/network/io-service;1']
+            .getService(SpecialPowers.Ci.nsIIOService);
     var chann = ios.newChannel(aFile, aCharset, baseUri);
 
-    var cis = Components.interfaces.nsIConverterInputStream;
+    var cis = SpecialPowers.Ci.nsIConverterInputStream;
 
-    var inputStream = Components.classes["@mozilla.org/intl/converter-input-stream;1"]
+    var inputStream = SpecialPowers.Cc["@mozilla.org/intl/converter-input-stream;1"]
                        .createInstance(cis);
     inputStream.init(chann.open(), aCharset, 1024, cis.DEFAULT_REPLACEMENT_CHARACTER);
     var str = {}, content = '';
     while (inputStream.readString(4096, str) != 0) {
         content += str.value;
     }
     return content;
 }
 
 function isRoughly(actual, expected, message) {
   return is(actual.replace("<!DOCTYPE HTML", "<!DOCTYPE html"), 
             expected, 
             message);
 }
 
 function testHtmlSerializer_1 () {
-  netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
-  const de = Components.interfaces.nsIDocumentEncoder
-  var encoder = Components.classes["@mozilla.org/layout/documentEncoder;1?type=text/html"]
-                   .createInstance(Components.interfaces.nsIDocumentEncoder);
+  const de = SpecialPowers.Ci.nsIDocumentEncoder;
+  var encoder = SpecialPowers.Cc["@mozilla.org/layout/documentEncoder;1?type=text/html"]
+                   .createInstance(SpecialPowers.Ci.nsIDocumentEncoder);
 
   var doc = $("testframe").contentDocument;
   var out, expected;
 
   // in the following tests, we must use the OutputLFLineBreak flag, to avoid
   // to have the default line break of the platform in the result, so the test
   // can pass on all platform
 
--- a/content/base/test/test_bug498433.html
+++ b/content/base/test/test_bug498433.html
@@ -17,47 +17,46 @@
 <pre id="test">
 <script class="testbody" type="text/javascript">
 
 
 function loadFileContent(aFile, aCharset) {
     if (aCharset == undefined)
         aCharset = 'UTF-8';
 
-    var baseUri = Components.classes['@mozilla.org/network/standard-url;1']
-                   .createInstance(Components.interfaces.nsIURI);
+    var baseUri = SpecialPowers.Cc['@mozilla.org/network/standard-url;1']
+                   .createInstance(SpecialPowers.Ci.nsIURI);
     baseUri.spec = window.location.href;
 
-    var ios = Components.classes['@mozilla.org/network/io-service;1']
-            .getService(Components.interfaces.nsIIOService);
+    var ios = SpecialPowers.Cc['@mozilla.org/network/io-service;1']
+            .getService(SpecialPowers.Ci.nsIIOService);
     var chann = ios.newChannel(aFile, aCharset, baseUri);
 
-    var cis = Components.interfaces.nsIConverterInputStream;
+    var cis = SpecialPowers.Ci.nsIConverterInputStream;
 
-    var inputStream = Components.classes["@mozilla.org/intl/converter-input-stream;1"]
+    var inputStream = SpecialPowers.Cc["@mozilla.org/intl/converter-input-stream;1"]
                        .createInstance(cis);
     inputStream.init(chann.open(), aCharset, 1024, cis.DEFAULT_REPLACEMENT_CHARACTER);
     var str = {}, content = '';
     while (inputStream.readString(4096, str) != 0) {
         content += str.value;
     }
     return content;
 }
 
 function isRoughly(actual, expected, message) {
   return is(actual.replace("<!DOCTYPE HTML", "<!DOCTYPE html"), 
             expected, 
             message);
 }
 
 function testHtmlSerializer_1 () {
-  netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
-  const de = Components.interfaces.nsIDocumentEncoder
-  var encoder = Components.classes["@mozilla.org/layout/documentEncoder;1?type=text/html"]
-                   .createInstance(Components.interfaces.nsIDocumentEncoder);
+  const de = SpecialPowers.Ci.nsIDocumentEncoder;
+  var encoder = SpecialPowers.Cc["@mozilla.org/layout/documentEncoder;1?type=text/html"]
+                   .createInstance(SpecialPowers.Ci.nsIDocumentEncoder);
 
   var doc = $("testframe").contentDocument;
   var out, expected;
 
   // in the following tests, we must use the OutputLFLineBreak flag, to avoid
   // to have the default line break of the platform in the result, so the test
   // can pass on all platform
 
--- a/content/base/test/test_bug498897.html
+++ b/content/base/test/test_bug498897.html
@@ -18,84 +18,74 @@ https://bugzilla.mozilla.org/show_bug.cg
 <script type="application/javascript">
 
 /** Test for Bug 498897 **/
 
 var checkedLoad = false;
 
 netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
 
-const Cc = Components.classes;
-const Ci = Components.interfaces;
+const Cc = SpecialPowers.Cc;
+const Ci = SpecialPowers.Ci;
 
 // Content policy / factory implementation for the test
-var policyID = Components.ID("{65944d64-2390-422e-bea3-80d0af7f69ef}");
+var policyID = SpecialPowers.wrap(SpecialPowers.Components).ID("{65944d64-2390-422e-bea3-80d0af7f69ef}");
 var policyName = "@mozilla.org/498897_testpolicy;1";
 var policy = {
   // nsISupports implementation
   QueryInterface: function(iid) {
-    netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
-
     if (iid.equals(Ci.nsISupports) ||
         iid.equals(Ci.nsIFactory) ||
         iid.equals(Ci.nsIContentPolicy))
       return this;
 
-    throw Components.results.NS_ERROR_NO_INTERFACE;
+    throw SpecialPowers.Cr.NS_ERROR_NO_INTERFACE;
   },
 
   // nsIFactory implementation
   createInstance: function(outer, iid) {
     return this.QueryInterface(iid);
   },
 
   // nsIContentPolicy implementation
   shouldLoad: function(contentType, contentLocation, requestOrigin, context,
                        mimeTypeGuess, extra) {
-    netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
-
     if (contentLocation instanceof Ci.nsIURL &&
         contentLocation.fileName == "file_bug498897.css" &&
         requestOrigin instanceof Ci.nsIURL &&
         requestOrigin.fileName == "file_bug498897.html") {
       checkedLoad = true;
     }
 
     return Ci.nsIContentPolicy.ACCEPT;
   },
 
   shouldProcess: function(contentType, contentLocation, requestOrigin, context,
                           mimeTypeGuess, extra) {
-    netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
-
     return Ci.nsIContentPolicy.ACCEPT;
   }
 }
 
-var componentManager = Components.manager
+var componentManager = SpecialPowers.wrap(SpecialPowers.Components).manager
                                  .QueryInterface(Ci.nsIComponentRegistrar);
 componentManager.registerFactory(policyID, "Test content policy for bug 498897",
                                  policyName, policy);
 
 var categoryManager =
   Cc["@mozilla.org/categorymanager;1"].getService(Ci.nsICategoryManager);
 categoryManager.addCategoryEntry("content-policy", policyName, policyName,
                                  false, true);
 
 function testFinished()
 {
-  netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
-
   ok(checkedLoad, "Content policy didn't get called!");
 
   categoryManager.deleteCategoryEntry("content-policy", policyName, false);
 
   setTimeout(function() {
-    netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
-
     componentManager.unregisterFactory(policyID, policy);
 
     SimpleTest.finish();
   }, 0);
 }
 
 SimpleTest.waitForExplicitFinish();
 
--- a/content/base/test/test_bug541937.html
+++ b/content/base/test/test_bug541937.html
@@ -16,20 +16,19 @@
   <iframe id="testframe2" src="file_bug541937.xhtml">
   </iframe>
 </div>
 
 <pre id="test">
 <script class="testbody" type="text/javascript">
 
 function testSerializer () {
-  netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
-  const de = Components.interfaces.nsIDocumentEncoder
-  var encoder = Components.classes["@mozilla.org/layout/documentEncoder;1?type=text/html"]
-                   .createInstance(Components.interfaces.nsIDocumentEncoder);
+  const de = SpecialPowers.Ci.nsIDocumentEncoder;
+  var encoder = SpecialPowers.Cc["@mozilla.org/layout/documentEncoder;1?type=text/html"]
+                   .createInstance(SpecialPowers.Ci.nsIDocumentEncoder);
 
   var parser = new DOMParser();
   var serializer = new XMLSerializer();
 
   // with content
   var str = '<?xml version="1.0"?><doc>\n<link xmlns="http://www.w3.org/1999/xhtml"><!-- child nodes -->  \n<content xmlns=""/></link>\n</doc>';
   var expected = '<?xml version="1.0" encoding="UTF-8"?>\n<doc>\n<link xmlns="http://www.w3.org/1999/xhtml"><!-- child nodes -->  \n<content xmlns=""/></link>\n</doc>';
 
--- a/content/base/test/test_bug578096.html
+++ b/content/base/test/test_bug578096.html
@@ -12,34 +12,31 @@ https://bugzilla.mozilla.org/show_bug.cg
 <body>
 <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=578096">Mozilla Bug 578096</a>
 <p id="display"></p>
 <div id="content">
    <input type="file" id="file" onchange="fireXHR()">
 </div>
 <pre id="test">
 <script class="testbody" type="text/javascript">
-netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
-
-const Cc = Components.classes;
-const Ci = Components.interfaces;
+const Cc = SpecialPowers.Cc;
+const Ci = SpecialPowers.Ci;
 
 var file = Cc["@mozilla.org/file/directory_service;1"]
            .getService(Ci.nsIProperties)
            .get("TmpD", Ci.nsIFile);
 file.append("foo.txt");
 file.createUnique(Ci.nsIFile.NORMAL_FILE_TYPE, 0600);
 
 SimpleTest.waitForExplicitFinish();
-document.getElementById('file').value = file.path;
+SpecialPowers.wrap(document.getElementById('file')).value = file.path;
 
 var xhr = new XMLHttpRequest();
 xhr.onreadystatechange = function(event) {
   if (xhr.readyState == 4) {
-    netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
     file.remove(false);
     ok(true, "We didn't throw! Yay!");
     SimpleTest.finish();
   }
 }
 xhr.open('POST', window.location, true);
 xhr.send(document.getElementById('file').files[0]);
 </script>
--- a/content/base/test/test_copyimage.html
+++ b/content/base/test/test_copyimage.html
@@ -11,35 +11,34 @@
 <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=518249">Mozilla Bug 518249</a>
 <p id="display"></p>
 <div id="content" style="display: none">
 </div>
 <pre id="test">
 <script class="testbody" type="text/javascript">
 
 function testCopyImage () {
-  netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
-
   // selection of the node
   var node = document.getElementById('logo');
-  var webnav = window.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
-                     .getInterface(Components.interfaces.nsIWebNavigation)
+  var webnav = SpecialPowers.wrap(window)
+               .QueryInterface(SpecialPowers.Ci.nsIInterfaceRequestor)
+               .getInterface(SpecialPowers.Ci.nsIWebNavigation)
 
-  var docShell = webnav.QueryInterface(Components.interfaces.nsIDocShell);
+  var docShell = webnav.QueryInterface(SpecialPowers.Ci.nsIDocShell);
 
   docShell.chromeEventHandler.ownerDocument.popupNode = node;
 
   // let's copy the node
   var documentViewer = docShell.contentViewer
-                               .QueryInterface(Components.interfaces.nsIContentViewerEdit);
+                               .QueryInterface(SpecialPowers.Ci.nsIContentViewerEdit);
   documentViewer.copyImage(documentViewer.COPY_IMAGE_ALL);
   
   //--------- now check the content of the clipboard
-  var clipboard = Components.classes["@mozilla.org/widget/clipboard;1"]
-                            .getService(Components.interfaces.nsIClipboard);
+  var clipboard = SpecialPowers.Cc["@mozilla.org/widget/clipboard;1"]
+                               .getService(SpecialPowers.Ci.nsIClipboard);
   
   // does the clipboard contain text/unicode data ?
   ok(clipboard.hasDataMatchingFlavors(["text/unicode"], 1, clipboard.kGlobalClipboard), "clipboard contains unicode text");
   // does the clipboard contain text/html data ?
   ok(clipboard.hasDataMatchingFlavors(["text/html"], 1, clipboard.kGlobalClipboard), "clipboard contains html text");
   // does the clipboard contain image data ?
   ok(clipboard.hasDataMatchingFlavors(["image/png"], 1, clipboard.kGlobalClipboard), "clipboard contains image");
 
--- a/content/base/test/test_fileapi.html
+++ b/content/base/test/test_fileapi.html
@@ -28,17 +28,16 @@ try {
   ok(true, "Threw on an unprivileged attempt to construct a File");
 }
 
 const minFileSize = 20000;
 var fileNum = 1;
 var testRanCounter = 0;
 var expectedTestCount = 0;
 SimpleTest.waitForExplicitFinish();
-netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
 
 is(FileReader.EMPTY, 0, "correct EMPTY value");
 is(FileReader.LOADING, 1, "correct LOADING value");
 is(FileReader.DONE, 2, "correct DONE value");
 
 // Create strings containing data we'll test with. We'll want long
 // strings to ensure they span multiple buffers while loading
 var testTextData = "asd b\tlah\u1234w\u00a0r";
@@ -60,17 +59,17 @@ while (testBinaryData.length < minFileSi
 }
 
 
 //Set up files for testing
 var asciiFile = createFileWithData(testASCIIData);
 var binaryFile = createFileWithData(testBinaryData);
 
 var fileList = document.getElementById('fileList');
-fileList.value = "/none/existing/path/fileAPI/testing";
+SpecialPowers.wrap(fileList).value = "/none/existing/path/fileAPI/testing";
 var nonExistingFile = fileList.files[0];
 
 // Test that plain reading works and fires events as expected, both
 // for text and binary reading
 
 var onloadHasRunText = false;
 var onloadStartHasRunText = false;
 r = new FileReader();
@@ -419,28 +418,28 @@ function testHasRun() {
  if (testRanCounter == expectedTestCount) {
     is(onloadHasRunText, true, "onload text should have fired by now"); 
     is(onloadHasRunBinary, true, "onload binary should have fired by now"); 
     SimpleTest.finish();
   }
 }
 
 function createFileWithData(fileData) {
-  var dirSvc = Components.classes["@mozilla.org/file/directory_service;1"].getService(Components.interfaces.nsIProperties);
-  var testFile = dirSvc.get("ProfD", Components.interfaces.nsIFile);
+  var dirSvc = SpecialPowers.Cc["@mozilla.org/file/directory_service;1"].getService(SpecialPowers.Ci.nsIProperties);
+  var testFile = dirSvc.get("ProfD", SpecialPowers.Ci.nsIFile);
   testFile.append("fileAPItestfile" + fileNum);
   fileNum++;
-  var outStream = Components.classes["@mozilla.org/network/file-output-stream;1"].createInstance(Components.interfaces.nsIFileOutputStream);
+  var outStream = SpecialPowers.Cc["@mozilla.org/network/file-output-stream;1"].createInstance(SpecialPowers.Ci.nsIFileOutputStream);
   outStream.init(testFile, 0x02 | 0x08 | 0x20, // write, create, truncate
                  0666, 0);
   outStream.write(fileData, fileData.length);
   outStream.close();
 
   var fileList = document.getElementById('fileList');
-  fileList.value = testFile.path;
+  SpecialPowers.wrap(fileList).value = testFile.path;
 
   return fileList.files[0];
 }
 
 function convertToUTF16(s) {
   res = "";
   for (var i = 0; i < s.length; ++i) {
     c = s.charCodeAt(i);
--- a/content/base/test/test_htmlcopyencoder.html
+++ b/content/base/test/test_htmlcopyencoder.html
@@ -11,20 +11,19 @@
 <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=422403">Mozilla Bug </a>
 <p id="display"></p>
 <div id="content" style="display: none">
 </div>
 <pre id="test">
 <script class="testbody" type="text/javascript">
 
 function testHtmlCopyEncoder () {
-  netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
-  const de = Components.interfaces.nsIDocumentEncoder;
-  var encoder = Components.classes["@mozilla.org/layout/htmlCopyEncoder;1"]
-                   .createInstance(Components.interfaces.nsIDocumentEncoder);
+  const de = SpecialPowers.Ci.nsIDocumentEncoder;
+  var encoder = SpecialPowers.Cc["@mozilla.org/layout/htmlCopyEncoder;1"]
+                   .createInstance(SpecialPowers.Ci.nsIDocumentEncoder);
   var out, expected;
 
   var node = document.getElementById('draggable');
 
 
   // in the following tests, we must use the OutputLFLineBreak flag, to avoid
   // to have the default line break of the platform in the result, so the test
   // can pass on all platform
--- a/content/base/test/test_htmlcopyencoder.xhtml
+++ b/content/base/test/test_htmlcopyencoder.xhtml
@@ -11,20 +11,19 @@
 <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=422403">Mozilla Bug </a>
 <p id="display"></p>
 <div id="content" style="display: none">
 </div>
 <pre id="test">
 <script class="testbody" type="text/javascript">
 //<![CDATA[
 function testHtmlCopyEncoder () {
-  netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
-  const de = Components.interfaces.nsIDocumentEncoder;
-  var encoder = Components.classes["@mozilla.org/layout/htmlCopyEncoder;1"]
-                   .createInstance(Components.interfaces.nsIDocumentEncoder);
+  const de = SpecialPowers.Ci.nsIDocumentEncoder;
+  var encoder = SpecialPowers.Cc["@mozilla.org/layout/htmlCopyEncoder;1"]
+                   .createInstance(SpecialPowers.Ci.nsIDocumentEncoder);
   var out, expected;
 
   var node = document.getElementById('draggable');
 
 
   // in the following tests, we must use the OutputLFLineBreak flag, to avoid
   // to have the default line break of the platform in the result, so the test
   // can pass on all platform
--- a/content/base/test/test_websocket.html
+++ b/content/base/test/test_websocket.html
@@ -1220,25 +1220,25 @@ function test41()
         wsc.close();
       }
 
       wsc.onclose = function(e)
       {
         ok(true, "test 41c close");
 
         // clean up the STS state
-        netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
-        const Cc = Components.classes;
-        const Ci = Components.interfaces;
+        const Cc = SpecialPowers.Cc;
+        const Ci = SpecialPowers.Ci;
         var ios = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService);
         var thehost = ios.newURI("http://example.com", null, null);
         var sss = Cc["@mozilla.org/ssservice;1"].getService(Ci.nsISiteSecurityService);
-        var loadContext = window.QueryInterface(Ci.nsIInterfaceRequestor)
-                                .getInterface(Ci.nsIWebNavigation)
-                                .QueryInterface(Ci.nsILoadContext);
+        var loadContext = SpecialPowers.wrap(window)
+                          .QueryInterface(Ci.nsIInterfaceRequestor)
+                          .getInterface(Ci.nsIWebNavigation)
+                          .QueryInterface(Ci.nsILoadContext);
         var flags = 0;
         if (loadContext.usePrivateBrowsing)
           flags |= Ci.nsISocketProvider.NO_PERMANENT_STORAGE;
         sss.removeState(Ci.nsISiteSecurityService.HEADER_HSTS, thehost, flags);
         doTest(42);
        }
      }
   }
@@ -1333,34 +1333,30 @@ function test44()
     ok(ws.readyState == 3, "onclose bad readyState in test-44!");
     shouldCloseCleanly(e);
     doTest(45);
   }
 }
 
 function createDOMFile(fileName, fileData)
 {
-  // enablePrivilege is picky about where it's called? if I put it in global
-  // scope at start of  <script> it doesn't work...
-  netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
-
   // create File in profile dir 
-  var dirSvc = Components.classes["@mozilla.org/file/directory_service;1"]
-                         .getService(Components.interfaces.nsIProperties);
-  var testFile = dirSvc.get("ProfD", Components.interfaces.nsIFile);
+  var dirSvc = SpecialPowers.Cc["@mozilla.org/file/directory_service;1"]
+                         .getService(SpecialPowers.Ci.nsIProperties);
+  var testFile = dirSvc.get("ProfD", SpecialPowers.Ci.nsIFile);
   testFile.append(fileName);
-  var outStream = Components.classes["@mozilla.org/network/file-output-stream;1"]
-                            .createInstance(Components.interfaces.nsIFileOutputStream);
+  var outStream = SpecialPowers.Cc["@mozilla.org/network/file-output-stream;1"]
+                            .createInstance(SpecialPowers.Ci.nsIFileOutputStream);
   outStream.init(testFile, 0x02 | 0x08 | 0x20, 0666, 0);
   outStream.write(fileData, fileData.length);
   outStream.close();
 
   // Set filename into DOM <input> field, as if selected by user 
   var fileList = document.getElementById('fileList');
-  fileList.value = testFile.path;
+  SpecialPowers.wrap(fileList).value = testFile.path;
 
   // return JS File object, aka Blob
   return fileList.files[0];
 }
 
 function test45()
 {
   var blobFile = createDOMFile("testBlobFile", "flob");
--- a/content/base/test/websocket_hybi/test_send-blob.html
+++ b/content/base/test/websocket_hybi/test_send-blob.html
@@ -17,36 +17,32 @@
 
 function startsWith(target, prefix)
 {
     return target.indexOf(prefix) === 0;
 }
 
 function createDOMFile(fileName, fileData)
 {
-    // enablePrivilege is picky about where it's called? if I put it in global
-    // scope at start of  <script> it doesn't work...
-    netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
-
     // create File in profile dir 
-    var dirSvc = Components.classes["@mozilla.org/file/directory_service;1"]
-                         .getService(Components.interfaces.nsIProperties);
-    var testFile = dirSvc.get("ProfD", Components.interfaces.nsIFile);
+    var dirSvc = SpecialPowers.Cc["@mozilla.org/file/directory_service;1"]
+                         .getService(SpecialPowers.Ci.nsIProperties);
+    var testFile = dirSvc.get("ProfD", SpecialPowers.Ci.nsIFile);
     testFile.append(fileName);
-    var outStream = Components.classes["@mozilla.org/network/file-output-stream;1"]
-                               .createInstance(Components.interfaces.nsIFileOutputStream);
+    var outStream = SpecialPowers.Cc["@mozilla.org/network/file-output-stream;1"]
+                               .createInstance(SpecialPowers.Ci.nsIFileOutputStream);
     outStream.init(testFile, 0x02 | 0x08 | 0x20, 0666, 0);
     if (fileData) {
         outStream.write(fileData, fileData.length);
         outStream.close();
     } 
 
     // Set filename into DOM <input> field, as if selected by user 
     var fileList = document.getElementById('fileList');
-    fileList.value = testFile.path;
+    SpecialPowers.wrap(fileList).value = testFile.path;
 
     // return JS File object, aka Blob
     return fileList.files[0];
 }
 
 
 function createBlobContainingHelloWorld()
 {
--- a/content/canvas/src/CanvasRenderingContext2D.cpp
+++ b/content/canvas/src/CanvasRenderingContext2D.cpp
@@ -869,17 +869,17 @@ CanvasRenderingContext2D::EnsureTarget()
 
         nsRefPtr<GLContext> glContext;
         nsCOMPtr<nsIGfxInfo> gfxInfo = do_GetService("@mozilla.org/gfx/info;1");
         nsString vendor;
 
         if (!mForceSoftware && CheckSizeForSkiaGL(size))
         {
           glContext = GLContextProvider::CreateOffscreen(gfxIntSize(size.width, size.height),
-                                                         caps, GLContext::ContextFlagsNone);
+                                                         caps, gl::ContextFlagsNone);
         }
 
         if (glContext) {
           SkAutoTUnref<GrGLInterface> i(CreateGrGLInterfaceFromGLContext(glContext));
           mTarget = Factory::CreateDrawTargetSkiaWithGLContextAndGrGLInterface(glContext, i, size, format);
           AddDemotableContext(this);
         } else {
           mTarget = layerManager->CreateDrawTarget(size, format);
--- a/content/canvas/src/WebGL2Context.cpp
+++ b/content/canvas/src/WebGL2Context.cpp
@@ -1,14 +1,15 @@
 /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
 /* 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/. */
 
 #include "WebGL2Context.h"
+#include "GLContext.h"
 #include "mozilla/dom/WebGL2RenderingContextBinding.h"
 
 #include "mozilla/Telemetry.h"
 
 using namespace mozilla;
 using namespace mozilla::gl;
 
 // -----------------------------------------------------------------------------
--- a/content/canvas/src/WebGLActiveInfo.h
+++ b/content/canvas/src/WebGLActiveInfo.h
@@ -1,51 +1,50 @@
 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
 /* 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/. */
 
 #ifndef WEBGLACTIVEINFO_H_
 #define WEBGLACTIVEINFO_H_
 
-#include "WebGLTypes.h"
-#include "nsISupports.h"
+#include "WebGLObjectModel.h"
 #include "nsString.h"
 #include "js/TypeDecls.h"
 
 namespace mozilla {
 
 class WebGLActiveInfo MOZ_FINAL
 {
 public:
-    WebGLActiveInfo(WebGLint size, WebGLenum type, const nsACString& name) :
+    WebGLActiveInfo(GLint size, GLenum type, const nsACString& name) :
         mSize(size),
         mType(type),
         mName(NS_ConvertASCIItoUTF16(name))
     {}
 
     // WebIDL attributes
 
-    WebGLint Size() const {
+    GLint Size() const {
         return mSize;
     }
 
-    WebGLenum Type() const {
+    GLenum Type() const {
         return mType;
     }
 
     void GetName(nsString& retval) const {
         retval = mName;
     }
 
     JSObject* WrapObject(JSContext *cx, JS::Handle<JSObject*> scope);
 
    NS_INLINE_DECL_REFCOUNTING(WebGLActiveInfo)
 
 protected:
-    WebGLint mSize;
-    WebGLenum mType;
+    GLint mSize;
+    GLenum mType;
     nsString mName;
 };
 
 } // namespace mozilla
 
 #endif
--- a/content/canvas/src/WebGLBuffer.cpp
+++ b/content/canvas/src/WebGLBuffer.cpp
@@ -1,15 +1,16 @@
 /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
 /* 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/. */
 
 #include "WebGLBuffer.h"
 #include "WebGLContext.h"
+#include "GLContext.h"
 #include "mozilla/dom/WebGLRenderingContextBinding.h"
 
 using namespace mozilla;
 
 WebGLBuffer::WebGLBuffer(WebGLContext *context)
     : WebGLContextBoundObject(context)
     , mHasEverBeenBound(false)
     , mByteLength(0)
--- a/content/canvas/src/WebGLBuffer.h
+++ b/content/canvas/src/WebGLBuffer.h
@@ -35,44 +35,44 @@ public:
     size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const {
         size_t sizeOfCache = mCache ? mCache->SizeOfIncludingThis(aMallocSizeOf) : 0;
         return aMallocSizeOf(this) + sizeOfCache;
     }
 
     bool HasEverBeenBound() { return mHasEverBeenBound; }
     void SetHasEverBeenBound(bool x) { mHasEverBeenBound = x; }
     GLuint GLName() const { return mGLName; }
-    GLuint ByteLength() const { return mByteLength; }
+    WebGLsizeiptr ByteLength() const { return mByteLength; }
     GLenum Target() const { return mTarget; }
 
-    void SetByteLength(GLuint byteLength) { mByteLength = byteLength; }
+    void SetByteLength(WebGLsizeiptr byteLength) { mByteLength = byteLength; }
 
     void SetTarget(GLenum target);
 
     bool ElementArrayCacheBufferData(const void* ptr, size_t buffer_size_in_bytes);
 
     void ElementArrayCacheBufferSubData(size_t pos, const void* ptr, size_t update_size_in_bytes);
 
-    bool Validate(WebGLenum type, uint32_t max_allowed, size_t first, size_t count) {
+    bool Validate(GLenum type, uint32_t max_allowed, size_t first, size_t count) {
         return mCache->Validate(type, max_allowed, first, count);
     }
 
     WebGLContext *GetParentObject() const {
         return Context();
     }
 
     virtual JSObject* WrapObject(JSContext *cx,
                                  JS::Handle<JSObject*> scope) MOZ_OVERRIDE;
 
     NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(WebGLBuffer)
     NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(WebGLBuffer)
 
 protected:
 
-    WebGLuint mGLName;
+    GLuint mGLName;
     bool mHasEverBeenBound;
-    GLuint mByteLength;
+    WebGLsizeiptr mByteLength;
     GLenum mTarget;
 
     nsAutoPtr<WebGLElementArrayCache> mCache;
 };
 }
 #endif //WEBGLBUFFER_H_
--- a/content/canvas/src/WebGLContext.cpp
+++ b/content/canvas/src/WebGLContext.cpp
@@ -32,16 +32,17 @@
 #include "gfxContext.h"
 #include "gfxPattern.h"
 #include "gfxUtils.h"
 
 #include "CanvasUtils.h"
 #include "nsDisplayList.h"
 
 #include "GLContextProvider.h"
+#include "GLContext.h"
 
 #include "gfxCrashReporterUtils.h"
 
 #include "nsSVGEffects.h"
 
 #include "prenv.h"
 
 #include "mozilla/Preferences.h"
@@ -179,17 +180,17 @@ WebGLContext::WebGLContext()
     mPixelStoreUnpackAlignment = 4;
 
     WebGLMemoryMultiReporterWrapper::AddWebGLContext(this);
 
     mAllowRestore = true;
     mContextLossTimerRunning = false;
     mDrawSinceContextLossTimerSet = false;
     mContextRestorer = do_CreateInstance("@mozilla.org/timer;1");
-    mContextStatus = ContextStable;
+    mContextStatus = ContextNotLost;
     mContextLostErrorSet = false;
     mLoseContextOnHeapMinimize = false;
     mCanLoseContextInForeground = true;
 
     mAlreadyGeneratedWarnings = 0;
     mAlreadyWarnedAboutFakeVertexAttrib0 = false;
     mMaxWarnings = Preferences::GetInt("webgl.max-warnings-per-context", 32);
     if (mMaxWarnings < -1)
@@ -525,19 +526,19 @@ WebGLContext::SetDimensions(int32_t widt
             GenerateWarning("Error during ANGLE OpenGL ES initialization");
             return NS_ERROR_FAILURE;
         }
     }
 #endif
 
     // try the default provider, whatever that is
     if (!gl && useOpenGL) {
-        GLContext::ContextFlags flag = useMesaLlvmPipe
-                                       ? GLContext::ContextFlagsMesaLLVMPipe
-                                       : GLContext::ContextFlagsNone;
+        gl::ContextFlags flag = useMesaLlvmPipe
+                                ? gl::ContextFlagsMesaLLVMPipe
+                                : gl::ContextFlagsNone;
         gl = gl::GLContextProvider::CreateOffscreen(size, caps, flag);
         if (gl && !InitAndValidateGL()) {
             GenerateWarning("Error during %s initialization",
                             useMesaLlvmPipe ? "Mesa LLVMpipe" : "OpenGL");
             return NS_ERROR_FAILURE;
         }
     }
 
@@ -839,17 +840,17 @@ private:
 
 } // end namespace mozilla
 
 already_AddRefed<layers::CanvasLayer>
 WebGLContext::GetCanvasLayer(nsDisplayListBuilder* aBuilder,
                              CanvasLayer *aOldLayer,
                              LayerManager *aManager)
 {
-    if (!IsContextStable())
+    if (IsContextLost())
         return nullptr;
 
     if (!mResetLayer && aOldLayer &&
         aOldLayer->HasUserData(&gWebGLLayerUserData)) {
         nsRefPtr<layers::CanvasLayer> ret = aOldLayer;
         return ret.forget();
     }
 
@@ -894,36 +895,36 @@ WebGLContext::GetCanvasLayer(nsDisplayLi
 
     return canvasLayer.forget();
 }
 
 void
 WebGLContext::GetContextAttributes(Nullable<dom::WebGLContextAttributesInitializer> &retval)
 {
     retval.SetNull();
-    if (!IsContextStable())
+    if (IsContextLost())
         return;
 
     dom::WebGLContextAttributes& result = retval.SetValue();
 
     const PixelBufferFormat& format = gl->GetPixelFormat();
 
     result.mAlpha.Construct(format.alpha > 0);
     result.mDepth = format.depth > 0;
     result.mStencil = format.stencil > 0;
     result.mAntialias = format.samples > 1;
     result.mPremultipliedAlpha = mOptions.premultipliedAlpha;
     result.mPreserveDrawingBuffer = mOptions.preserveDrawingBuffer;
 }
 
-/* [noscript] DOMString mozGetUnderlyingParamString(in WebGLenum pname); */
+/* [noscript] DOMString mozGetUnderlyingParamString(in GLenum pname); */
 NS_IMETHODIMP
 WebGLContext::MozGetUnderlyingParamString(uint32_t pname, nsAString& retval)
 {
-    if (!IsContextStable())
+    if (IsContextLost())
         return NS_OK;
 
     retval.SetIsVoid(true);
 
     MakeContextCurrent();
 
     switch (pname) {
     case LOCAL_GL_VENDOR:
@@ -1151,17 +1152,17 @@ WebGLContext::PresentScreenBuffer()
     mShouldPresent = false;
 
     return true;
 }
 
 void
 WebGLContext::DummyFramebufferOperation(const char *info)
 {
-    WebGLenum status = CheckFramebufferStatus(LOCAL_GL_FRAMEBUFFER);
+    GLenum status = CheckFramebufferStatus(LOCAL_GL_FRAMEBUFFER);
     if (status == LOCAL_GL_FRAMEBUFFER_COMPLETE)
         return;
     else
         return ErrorInvalidFramebufferOperation("%s: incomplete framebuffer", info);
 }
 
 // We use this timer for many things. Here are the things that it is activated for:
 // 1) If a script is using the MOZ_WEBGL_lose_context extension.
@@ -1215,17 +1216,17 @@ WebGLContext::RobustnessTimerCallback(ns
             mContextStatus = ContextLost;
         }
     } else if (mContextStatus == ContextLostAwaitingRestore) {
         // Try to restore the context. If it fails, try again later.
         if (NS_FAILED(SetDimensions(mWidth, mHeight))) {
             SetupContextLossTimer();
             return;
         }
-        mContextStatus = ContextStable;
+        mContextStatus = ContextNotLost;
         nsContentUtils::DispatchTrustedEvent(mCanvasElement->OwnerDoc(),
                                              static_cast<nsIDOMHTMLCanvasElement*>(mCanvasElement),
                                              NS_LITERAL_STRING("webglcontextrestored"),
                                              true,
                                              true);
         // Set all flags back to the state they were in before the context was
         // lost.
         mContextLostErrorSet = false;
@@ -1235,20 +1236,20 @@ WebGLContext::RobustnessTimerCallback(ns
     MaybeRestoreContext();
     return;
 }
 
 void
 WebGLContext::MaybeRestoreContext()
 {
     // Don't try to handle it if we already know it's busted.
-    if (mContextStatus != ContextStable || gl == nullptr)
+    if (mContextStatus != ContextNotLost || gl == nullptr)
         return;
 
-    bool isEGL = gl->GetContextType() == GLContext::ContextTypeEGL,
+    bool isEGL = gl->GetContextType() == gl::ContextTypeEGL,
          isANGLE = gl->IsANGLE();
 
     GLContext::ContextResetARB resetStatus = GLContext::CONTEXT_NO_ERROR;
     if (mHasRobustness) {
         gl->MakeCurrent();
         resetStatus = (GLContext::ContextResetARB) gl->fGetGraphicsResetStatus();
     } else if (isEGL) {
         // Simulate a ARB_robustness guilty context loss for when we
@@ -1306,34 +1307,38 @@ WebGLContext::ForceLoseContext()
 }
 
 void
 WebGLContext::ForceRestoreContext()
 {
     mContextStatus = ContextLostAwaitingRestore;
 }
 
+void
+WebGLContext::MakeContextCurrent() const { gl->MakeCurrent(); }
+
 //
 // XPCOM goop
 //
 
 NS_IMPL_CYCLE_COLLECTING_ADDREF(WebGLContext)
 NS_IMPL_CYCLE_COLLECTING_RELEASE(WebGLContext)
 
-NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_12(WebGLContext,
+NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_13(WebGLContext,
   mCanvasElement,
   mExtensions,
   mBound2DTextures,
   mBoundCubeMapTextures,
   mBoundArrayBuffer,
   mBoundTransformFeedbackBuffer,
   mCurrentProgram,
   mBoundFramebuffer,
   mBoundRenderbuffer,
   mBoundVertexArray,
+  mDefaultVertexArray,
   mActiveOcclusionQuery,
   mActiveTransformFeedbackQuery)
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(WebGLContext)
   NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
   NS_INTERFACE_MAP_ENTRY(nsIDOMWebGLRenderingContext)
   NS_INTERFACE_MAP_ENTRY(nsICanvasRenderingContextInternal)
   NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
--- a/content/canvas/src/WebGLContext.h
+++ b/content/canvas/src/WebGLContext.h
@@ -178,53 +178,47 @@ public:
                     { return NS_ERROR_NOT_IMPLEMENTED; }
     NS_IMETHOD Swap(uint32_t nativeID,
                     int32_t x, int32_t y, int32_t w, int32_t h)
                     { return NS_ERROR_NOT_IMPLEMENTED; }
 
     bool LoseContext();
     bool RestoreContext();
 
-    void SynthesizeGLError(WebGLenum err);
-    void SynthesizeGLError(WebGLenum err, const char *fmt, ...);
+    void SynthesizeGLError(GLenum err);
+    void SynthesizeGLError(GLenum err, const char *fmt, ...);
 
     void ErrorInvalidEnum(const char *fmt = 0, ...);
     void ErrorInvalidOperation(const char *fmt = 0, ...);
     void ErrorInvalidValue(const char *fmt = 0, ...);
     void ErrorInvalidFramebufferOperation(const char *fmt = 0, ...);
-    void ErrorInvalidEnumInfo(const char *info, WebGLenum enumvalue) {
-        return ErrorInvalidEnum("%s: invalid enum value 0x%x", info, enumvalue);
-    }
+    void ErrorInvalidEnumInfo(const char *info, GLenum enumvalue);
     void ErrorOutOfMemory(const char *fmt = 0, ...);
 
     const char *ErrorName(GLenum error);
     bool IsTextureFormatCompressed(GLenum format);
 
     void DummyFramebufferOperation(const char *info);
 
-    WebGLTexture *activeBoundTextureForTarget(WebGLenum target) {
+    WebGLTexture *activeBoundTextureForTarget(GLenum target) const {
         return target == LOCAL_GL_TEXTURE_2D ? mBound2DTextures[mActiveTexture]
                                              : mBoundCubeMapTextures[mActiveTexture];
     }
 
     already_AddRefed<CanvasLayer> GetCanvasLayer(nsDisplayListBuilder* aBuilder,
                                                  CanvasLayer *aOldLayer,
                                                  LayerManager *aManager) MOZ_OVERRIDE;
 
     // Note that 'clean' here refers to its invalidation state, not the
     // contents of the buffer.
     void MarkContextClean() MOZ_OVERRIDE { mInvalidated = false; }
 
-    gl::GLContext* GL() const {
-        return gl;
-    }
+    gl::GLContext* GL() const { return gl; }
 
-    bool IsPremultAlpha() const {
-        return mOptions.premultipliedAlpha;
-    }
+    bool IsPremultAlpha() const { return mOptions.premultipliedAlpha; }
 
     bool PresentScreenBuffer();
 
     // a number that increments every time we have an event that causes
     // all context resources to be lost.
     uint32_t Generation() { return mGeneration.value(); }
 
     const WebGLRectangleObject *FramebufferRectangleObject() const;
@@ -235,313 +229,232 @@ public:
     // amount of work it does.
     // It only clears the buffers we specify, and can reset its state without
     // first having to query anything, as WebGL knows its state at all times.
     void ForceClearFramebufferWithDefaultValues(GLbitfield mask, const bool colorAttachmentsMask[sMaxColorAttachments]);
 
     // Calls ForceClearFramebufferWithDefaultValues() for the Context's 'screen'.
     void ClearScreen();
 
-    // checks for GL errors, clears any pending GL error, stores the current GL error in currentGLError,
+    // checks for GL errors, clears any pending GL error, stores the current GL error in currentGLError (if not nullptr),
     // and copies it into mWebGLError if it doesn't already have an error set
-    void UpdateWebGLErrorAndClearGLError(GLenum *currentGLError) {
-        // get and clear GL error in ALL cases
-        *currentGLError = gl->GetAndClearError();
-        // only store in mWebGLError if is hasn't already recorded an error
-        if (!mWebGLError)
-            mWebGLError = *currentGLError;
-    }
-    
-    // checks for GL errors, clears any pending GL error,
-    // and stores the current GL error into mWebGLError if it doesn't already have an error set
-    void UpdateWebGLErrorAndClearGLError() {
-        GLenum currentGLError;
-        UpdateWebGLErrorAndClearGLError(&currentGLError);
-    }
-    
-    bool MinCapabilityMode() const {
-        return mMinCapability;
-    }
+    void UpdateWebGLErrorAndClearGLError(GLenum *currentGLError = nullptr);
+
+    bool MinCapabilityMode() const { return mMinCapability; }
 
     void RobustnessTimerCallback(nsITimer* timer);
-
-    static void RobustnessTimerCallbackStatic(nsITimer* timer, void *thisPointer) {
-        static_cast<WebGLContext*>(thisPointer)->RobustnessTimerCallback(timer);
-    }
-
-    void SetupContextLossTimer() {
-        // If the timer was already running, don't restart it here. Instead,
-        // wait until the previous call is done, then fire it one more time.
-        // This is an optimization to prevent unnecessary cross-communication
-        // between threads.
-        if (mContextLossTimerRunning) {
-            mDrawSinceContextLossTimerSet = true;
-            return;
-        }
-
-        mContextRestorer->InitWithFuncCallback(RobustnessTimerCallbackStatic,
-                                               static_cast<void*>(this),
-                                               1000,
-                                               nsITimer::TYPE_ONE_SHOT);
-        mContextLossTimerRunning = true;
-        mDrawSinceContextLossTimerSet = false;
-    }
-
-    void TerminateContextLossTimer() {
-        if (mContextLossTimerRunning) {
-            mContextRestorer->Cancel();
-            mContextLossTimerRunning = false;
-        }
-    }
+    static void RobustnessTimerCallbackStatic(nsITimer* timer, void *thisPointer);
+    void SetupContextLossTimer();
+    void TerminateContextLossTimer();
 
     // WebIDL WebGLRenderingContext API
-    dom::HTMLCanvasElement* GetCanvas() const {
-        return mCanvasElement;
-    }
-    WebGLsizei DrawingBufferWidth() const {
-        if (!IsContextStable())
-            return 0;
-        return mWidth;
-    }
-    WebGLsizei DrawingBufferHeight() const {
-        if (!IsContextStable())
-            return 0;
-        return mHeight;
-    }
-        
+    dom::HTMLCanvasElement* GetCanvas() const { return mCanvasElement; }
+    GLsizei DrawingBufferWidth() const { return IsContextLost() ? 0 : mWidth; }
+    GLsizei DrawingBufferHeight() const { return IsContextLost() ? 0 : mHeight; }
+
     void GetContextAttributes(dom::Nullable<dom::WebGLContextAttributesInitializer>& retval);
-    bool IsContextLost() const { return !IsContextStable(); }
+    bool IsContextLost() const { return mContextStatus != ContextNotLost; }
     void GetSupportedExtensions(JSContext *cx, dom::Nullable< nsTArray<nsString> > &retval);
     JSObject* GetExtension(JSContext* cx, const nsAString& aName, ErrorResult& rv);
-    void ActiveTexture(WebGLenum texture);
+    void ActiveTexture(GLenum texture);
     void AttachShader(WebGLProgram* program, WebGLShader* shader);
-    void BindAttribLocation(WebGLProgram* program, WebGLuint location,
+    void BindAttribLocation(WebGLProgram* program, GLuint location,
                             const nsAString& name);
-    void BindFramebuffer(WebGLenum target, WebGLFramebuffer* wfb);
-    void BindRenderbuffer(WebGLenum target, WebGLRenderbuffer* wrb);
-    void BindTexture(WebGLenum target, WebGLTexture *tex);
+    void BindFramebuffer(GLenum target, WebGLFramebuffer* wfb);
+    void BindRenderbuffer(GLenum target, WebGLRenderbuffer* wrb);
+    void BindTexture(GLenum target, WebGLTexture *tex);
     void BindVertexArray(WebGLVertexArray *vao);
-    void BlendColor(WebGLclampf r, WebGLclampf g, WebGLclampf b, WebGLclampf a) {
-        if (!IsContextStable())
-            return;
-        MakeContextCurrent();
-        gl->fBlendColor(r, g, b, a);
-    }
-    void BlendEquation(WebGLenum mode);
-    void BlendEquationSeparate(WebGLenum modeRGB, WebGLenum modeAlpha);
-    void BlendFunc(WebGLenum sfactor, WebGLenum dfactor);
-    void BlendFuncSeparate(WebGLenum srcRGB, WebGLenum dstRGB,
-                           WebGLenum srcAlpha, WebGLenum dstAlpha);
-    WebGLenum CheckFramebufferStatus(WebGLenum target);
-    void Clear(WebGLbitfield mask);
-    void ClearColor(WebGLclampf r, WebGLclampf g, WebGLclampf b, WebGLclampf a);
-    void ClearDepth(WebGLclampf v);
-    void ClearStencil(WebGLint v);
+    void BlendColor(GLclampf r, GLclampf g, GLclampf b, GLclampf a);
+    void BlendEquation(GLenum mode);
+    void BlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha);
+    void BlendFunc(GLenum sfactor, GLenum dfactor);
+    void BlendFuncSeparate(GLenum srcRGB, GLenum dstRGB,
+                           GLenum srcAlpha, GLenum dstAlpha);
+    GLenum CheckFramebufferStatus(GLenum target);
+    void Clear(GLbitfield mask);
+    void ClearColor(GLclampf r, GLclampf g, GLclampf b, GLclampf a);
+    void ClearDepth(GLclampf v);
+    void ClearStencil(GLint v);
     void ColorMask(WebGLboolean r, WebGLboolean g, WebGLboolean b, WebGLboolean a);
     void CompileShader(WebGLShader *shader);
-    void CompressedTexImage2D(WebGLenum target, WebGLint level,
-                              WebGLenum internalformat, WebGLsizei width,
-                              WebGLsizei height, WebGLint border,
+    void CompressedTexImage2D(GLenum target, GLint level,
+                              GLenum internalformat, GLsizei width,
+                              GLsizei height, GLint border,
                               const dom::ArrayBufferView& view);
-    void CompressedTexSubImage2D(WebGLenum target, WebGLint level,
-                                 WebGLint xoffset, WebGLint yoffset,
-                                 WebGLsizei width, WebGLsizei height,
-                                 WebGLenum format,
+    void CompressedTexSubImage2D(GLenum target, GLint level,
+                                 GLint xoffset, GLint yoffset,
+                                 GLsizei width, GLsizei height,
+                                 GLenum format,
                                  const dom::ArrayBufferView& view);
-    void CopyTexImage2D(WebGLenum target, WebGLint level,
-                        WebGLenum internalformat, WebGLint x, WebGLint y,
-                        WebGLsizei width, WebGLsizei height, WebGLint border);
-    void CopyTexSubImage2D(WebGLenum target, WebGLint level, WebGLint xoffset,
-                           WebGLint yoffset, WebGLint x, WebGLint y,
-                           WebGLsizei width, WebGLsizei height);
+    void CopyTexImage2D(GLenum target, GLint level,
+                        GLenum internalformat, GLint x, GLint y,
+                        GLsizei width, GLsizei height, GLint border);
+    void CopyTexSubImage2D(GLenum target, GLint level, GLint xoffset,
+                           GLint yoffset, GLint x, GLint y,
+                           GLsizei width, GLsizei height);
     already_AddRefed<WebGLFramebuffer> CreateFramebuffer();
     already_AddRefed<WebGLProgram> CreateProgram();
     already_AddRefed<WebGLRenderbuffer> CreateRenderbuffer();
     already_AddRefed<WebGLTexture> CreateTexture();
-    already_AddRefed<WebGLShader> CreateShader(WebGLenum type);
+    already_AddRefed<WebGLShader> CreateShader(GLenum type);
     already_AddRefed<WebGLVertexArray> CreateVertexArray();
-    void CullFace(WebGLenum face);
+    void CullFace(GLenum face);
     void DeleteFramebuffer(WebGLFramebuffer *fbuf);
     void DeleteProgram(WebGLProgram *prog);
     void DeleteRenderbuffer(WebGLRenderbuffer *rbuf);
     void DeleteShader(WebGLShader *shader);
     void DeleteVertexArray(WebGLVertexArray *vao);
     void DeleteTexture(WebGLTexture *tex);
-    void DepthFunc(WebGLenum func);
+    void DepthFunc(GLenum func);
     void DepthMask(WebGLboolean b);
-    void DepthRange(WebGLclampf zNear, WebGLclampf zFar);
+    void DepthRange(GLclampf zNear, GLclampf zFar);
     void DetachShader(WebGLProgram *program, WebGLShader *shader);
     void DrawBuffers(const dom::Sequence<GLenum>& buffers);
-    void Flush() {
-        if (!IsContextStable())
-            return;
-        MakeContextCurrent();
-        gl->fFlush();
-    }
-    void Finish() {
-        if (!IsContextStable())
-            return;
-        MakeContextCurrent();
-        gl->fFinish();
-    }
-    void FramebufferRenderbuffer(WebGLenum target, WebGLenum attachment,
-                                 WebGLenum rbtarget, WebGLRenderbuffer *wrb);
-    void FramebufferTexture2D(WebGLenum target, WebGLenum attachment,
-                              WebGLenum textarget, WebGLTexture *tobj,
-                              WebGLint level);
-    void FrontFace(WebGLenum mode);
-    void GenerateMipmap(WebGLenum target);
+    void Flush();
+    void Finish();
+    void FramebufferRenderbuffer(GLenum target, GLenum attachment,
+                                 GLenum rbtarget, WebGLRenderbuffer *wrb);
+    void FramebufferTexture2D(GLenum target, GLenum attachment,
+                              GLenum textarget, WebGLTexture *tobj,
+                              GLint level);
+    void FrontFace(GLenum mode);
+    void GenerateMipmap(GLenum target);
     already_AddRefed<WebGLActiveInfo> GetActiveAttrib(WebGLProgram *prog,
-                                                      WebGLuint index);
+                                                      GLuint index);
     already_AddRefed<WebGLActiveInfo> GetActiveUniform(WebGLProgram *prog,
-                                                       WebGLuint index);
+                                                       GLuint index);
     void GetAttachedShaders(WebGLProgram* prog,
                             dom::Nullable< nsTArray<WebGLShader*> > &retval);
-    WebGLint GetAttribLocation(WebGLProgram* prog, const nsAString& name);
-    JS::Value GetBufferParameter(WebGLenum target, WebGLenum pname);
-    JS::Value GetBufferParameter(JSContext* /* unused */, WebGLenum target,
-                                 WebGLenum pname) {
+    GLint GetAttribLocation(WebGLProgram* prog, const nsAString& name);
+    JS::Value GetBufferParameter(GLenum target, GLenum pname);
+    JS::Value GetBufferParameter(JSContext* /* unused */, GLenum target,
+                                 GLenum pname) {
         return GetBufferParameter(target, pname);
     }
-    WebGLenum GetError();
+    GLenum GetError();
     JS::Value GetFramebufferAttachmentParameter(JSContext* cx,
-                                                WebGLenum target,
-                                                WebGLenum attachment,
-                                                WebGLenum pname,
+                                                GLenum target,
+                                                GLenum attachment,
+                                                GLenum pname,
                                                 ErrorResult& rv);
-    JS::Value GetProgramParameter(WebGLProgram *prog, WebGLenum pname);
+    JS::Value GetProgramParameter(WebGLProgram *prog, GLenum pname);
     JS::Value GetProgramParameter(JSContext* /* unused */, WebGLProgram *prog,
-                                  WebGLenum pname) {
+                                  GLenum pname) {
         return GetProgramParameter(prog, pname);
     }
     void GetProgramInfoLog(WebGLProgram *prog, nsACString& retval);
     void GetProgramInfoLog(WebGLProgram *prog, nsAString& retval);
-    JS::Value GetRenderbufferParameter(WebGLenum target, WebGLenum pname);
+    JS::Value GetRenderbufferParameter(GLenum target, GLenum pname);
     JS::Value GetRenderbufferParameter(JSContext* /* unused */,
-                                       WebGLenum target, WebGLenum pname) {
+                                       GLenum target, GLenum pname) {
         return GetRenderbufferParameter(target, pname);
     }
-    JS::Value GetShaderParameter(WebGLShader *shader, WebGLenum pname);
+    JS::Value GetShaderParameter(WebGLShader *shader, GLenum pname);
     JS::Value GetShaderParameter(JSContext* /* unused */, WebGLShader *shader,
-                                 WebGLenum pname) {
+                                 GLenum pname) {
         return GetShaderParameter(shader, pname);
     }
     already_AddRefed<WebGLShaderPrecisionFormat>
-      GetShaderPrecisionFormat(WebGLenum shadertype, WebGLenum precisiontype);
+      GetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype);
     void GetShaderInfoLog(WebGLShader *shader, nsACString& retval);
     void GetShaderInfoLog(WebGLShader *shader, nsAString& retval);
     void GetShaderSource(WebGLShader *shader, nsAString& retval);
-    JS::Value GetTexParameter(WebGLenum target, WebGLenum pname);
-    JS::Value GetTexParameter(JSContext * /* unused */, WebGLenum target,
-                              WebGLenum pname) {
+    JS::Value GetTexParameter(GLenum target, GLenum pname);
+    JS::Value GetTexParameter(JSContext * /* unused */, GLenum target,
+                              GLenum pname) {
         return GetTexParameter(target, pname);
     }
     JS::Value GetUniform(JSContext* cx, WebGLProgram *prog,
                          WebGLUniformLocation *location, ErrorResult& rv);
     already_AddRefed<WebGLUniformLocation>
       GetUniformLocation(WebGLProgram *prog, const nsAString& name);
-    void Hint(WebGLenum target, WebGLenum mode);
+    void Hint(GLenum target, GLenum mode);
     bool IsFramebuffer(WebGLFramebuffer *fb);
     bool IsProgram(WebGLProgram *prog);
     bool IsRenderbuffer(WebGLRenderbuffer *rb);
     bool IsShader(WebGLShader *shader);
     bool IsTexture(WebGLTexture *tex);
     bool IsVertexArray(WebGLVertexArray *vao);
-    void LineWidth(WebGLfloat width) {
-        if (!IsContextStable())
-            return;
-        MakeContextCurrent();
-        gl->fLineWidth(width);
-    }
+    void LineWidth(GLfloat width);
     void LinkProgram(WebGLProgram *program);
-    void PixelStorei(WebGLenum pname, WebGLint param);
-    void PolygonOffset(WebGLfloat factor, WebGLfloat units) {
-        if (!IsContextStable())
-            return;
-        MakeContextCurrent();
-        gl->fPolygonOffset(factor, units);
-    }
-    void ReadPixels(WebGLint x, WebGLint y, WebGLsizei width, WebGLsizei height,
-                    WebGLenum format, WebGLenum type,
+    void PixelStorei(GLenum pname, GLint param);
+    void PolygonOffset(GLfloat factor, GLfloat units);
+    void ReadPixels(GLint x, GLint y, GLsizei width, GLsizei height,
+                    GLenum format, GLenum type,
                     const Nullable<dom::ArrayBufferView> &pixels,
                     ErrorResult& rv);
-    void RenderbufferStorage(WebGLenum target, WebGLenum internalformat,
-                             WebGLsizei width, WebGLsizei height);
-    void SampleCoverage(WebGLclampf value, WebGLboolean invert) {
-        if (!IsContextStable())
-            return;
-        MakeContextCurrent();
-        gl->fSampleCoverage(value, invert);
-    }
-    void Scissor(WebGLint x, WebGLint y, WebGLsizei width, WebGLsizei height);
+    void RenderbufferStorage(GLenum target, GLenum internalformat,
+                             GLsizei width, GLsizei height);
+    void SampleCoverage(GLclampf value, WebGLboolean invert);
+    void Scissor(GLint x, GLint y, GLsizei width, GLsizei height);
     void ShaderSource(WebGLShader *shader, const nsAString& source);
-    void StencilFunc(WebGLenum func, WebGLint ref, WebGLuint mask);
-    void StencilFuncSeparate(WebGLenum face, WebGLenum func, WebGLint ref,
-                             WebGLuint mask);
-    void StencilMask(WebGLuint mask);
-    void StencilMaskSeparate(WebGLenum face, WebGLuint mask);
-    void StencilOp(WebGLenum sfail, WebGLenum dpfail, WebGLenum dppass);
-    void StencilOpSeparate(WebGLenum face, WebGLenum sfail, WebGLenum dpfail,
-                           WebGLenum dppass);
-    void TexImage2D(WebGLenum target, WebGLint level,
-                    WebGLenum internalformat, WebGLsizei width,
-                    WebGLsizei height, WebGLint border, WebGLenum format,
-                    WebGLenum type,
+    void StencilFunc(GLenum func, GLint ref, GLuint mask);
+    void StencilFuncSeparate(GLenum face, GLenum func, GLint ref,
+                             GLuint mask);
+    void StencilMask(GLuint mask);
+    void StencilMaskSeparate(GLenum face, GLuint mask);
+    void StencilOp(GLenum sfail, GLenum dpfail, GLenum dppass);
+    void StencilOpSeparate(GLenum face, GLenum sfail, GLenum dpfail,
+                           GLenum dppass);
+    void TexImage2D(GLenum target, GLint level,
+                    GLenum internalformat, GLsizei width,
+                    GLsizei height, GLint border, GLenum format,
+                    GLenum type,
                     const Nullable<dom::ArrayBufferView> &pixels,
                     ErrorResult& rv);
-    void TexImage2D(WebGLenum target, WebGLint level,
-                    WebGLenum internalformat, WebGLenum format, WebGLenum type,
+    void TexImage2D(GLenum target, GLint level,
+                    GLenum internalformat, GLenum format, GLenum type,
                     dom::ImageData* pixels, ErrorResult& rv);
     // Allow whatever element types the bindings are willing to pass
     // us in TexImage2D
     template<class ElementType>
-    void TexImage2D(WebGLenum target, WebGLint level,
-                    WebGLenum internalformat, WebGLenum format, WebGLenum type,
+    void TexImage2D(GLenum target, GLint level,
+                    GLenum internalformat, GLenum format, GLenum type,
                     ElementType& elt, ErrorResult& rv)
     {
-        if (!IsContextStable())
+        if (IsContextLost())
             return;
         nsRefPtr<gfxImageSurface> isurf;
         WebGLTexelFormat srcFormat;
         nsLayoutUtils::SurfaceFromElementResult res = SurfaceFromElement(elt);
         rv = SurfaceFromElementResultToImageSurface(res, getter_AddRefs(isurf),
                                                     &srcFormat);
         if (rv.Failed())
             return;
 
         uint32_t byteLength = isurf->Stride() * isurf->Height();
         return TexImage2D_base(target, level, internalformat,
                                isurf->Width(), isurf->Height(), isurf->Stride(),
                                0, format, type, isurf->Data(), byteLength,
                                -1, srcFormat, mPixelStorePremultiplyAlpha);
     }
-    void TexParameterf(WebGLenum target, WebGLenum pname, WebGLfloat param) {
+    void TexParameterf(GLenum target, GLenum pname, GLfloat param) {
         TexParameter_base(target, pname, nullptr, &param);
     }
-    void TexParameteri(WebGLenum target, WebGLenum pname, WebGLint param) {
+    void TexParameteri(GLenum target, GLenum pname, GLint param) {
         TexParameter_base(target, pname, &param, nullptr);
     }
     
-    void TexSubImage2D(WebGLenum target, WebGLint level,
-                       WebGLint xoffset, WebGLint yoffset,
-                       WebGLsizei width, WebGLsizei height, WebGLenum format,
-                       WebGLenum type,
+    void TexSubImage2D(GLenum target, GLint level,
+                       GLint xoffset, GLint yoffset,
+                       GLsizei width, GLsizei height, GLenum format,
+                       GLenum type,
                        const Nullable<dom::ArrayBufferView> &pixels,
                        ErrorResult& rv);
-    void TexSubImage2D(WebGLenum target, WebGLint level,
-                       WebGLint xoffset, WebGLint yoffset, WebGLenum format,
-                       WebGLenum type, dom::ImageData* pixels, ErrorResult& rv);
+    void TexSubImage2D(GLenum target, GLint level,
+                       GLint xoffset, GLint yoffset, GLenum format,
+                       GLenum type, dom::ImageData* pixels, ErrorResult& rv);
     // Allow whatever element types the bindings are willing to pass
     // us in TexSubImage2D
     template<class ElementType>
-    void TexSubImage2D(WebGLenum target, WebGLint level,
-                       WebGLint xoffset, WebGLint yoffset, WebGLenum format,
-                       WebGLenum type, ElementType& elt, ErrorResult& rv)
+    void TexSubImage2D(GLenum target, GLint level,
+                       GLint xoffset, GLint yoffset, GLenum format,
+                       GLenum type, ElementType& elt, ErrorResult& rv)
     {
-        if (!IsContextStable())
+        if (IsContextLost())
             return;
         nsRefPtr<gfxImageSurface> isurf;
         WebGLTexelFormat srcFormat;
         nsLayoutUtils::SurfaceFromElementResult res = SurfaceFromElement(elt);
         rv = SurfaceFromElementResultToImageSurface(res, getter_AddRefs(isurf),
                                                     &srcFormat);
         if (rv.Failed())
             return;
@@ -550,117 +463,117 @@ public:
         return TexSubImage2D_base(target, level, xoffset, yoffset,
                                   isurf->Width(), isurf->Height(),
                                   isurf->Stride(), format, type,
                                   isurf->Data(), byteLength,
                                   -1, srcFormat, mPixelStorePremultiplyAlpha);
         
     }
 
-    void Uniform1i(WebGLUniformLocation* location, WebGLint x);
-    void Uniform2i(WebGLUniformLocation* location, WebGLint x, WebGLint y);
-    void Uniform3i(WebGLUniformLocation* location, WebGLint x, WebGLint y,
-                   WebGLint z);
-    void Uniform4i(WebGLUniformLocation* location, WebGLint x, WebGLint y,
-                   WebGLint z, WebGLint w);
+    void Uniform1i(WebGLUniformLocation* location, GLint x);
+    void Uniform2i(WebGLUniformLocation* location, GLint x, GLint y);
+    void Uniform3i(WebGLUniformLocation* location, GLint x, GLint y,
+                   GLint z);
+    void Uniform4i(WebGLUniformLocation* location, GLint x, GLint y,
+                   GLint z, GLint w);
 
-    void Uniform1f(WebGLUniformLocation* location, WebGLfloat x);
-    void Uniform2f(WebGLUniformLocation* location, WebGLfloat x, WebGLfloat y);
-    void Uniform3f(WebGLUniformLocation* location, WebGLfloat x, WebGLfloat y,
-                   WebGLfloat z);
-    void Uniform4f(WebGLUniformLocation* location, WebGLfloat x, WebGLfloat y,
-                   WebGLfloat z, WebGLfloat w);
+    void Uniform1f(WebGLUniformLocation* location, GLfloat x);
+    void Uniform2f(WebGLUniformLocation* location, GLfloat x, GLfloat y);
+    void Uniform3f(WebGLUniformLocation* location, GLfloat x, GLfloat y,
+                   GLfloat z);
+    void Uniform4f(WebGLUniformLocation* location, GLfloat x, GLfloat y,
+                   GLfloat z, GLfloat w);
     
     void Uniform1iv(WebGLUniformLocation* location,
                     const dom::Int32Array& arr) {
         Uniform1iv_base(location, arr.Length(), arr.Data());
     }
     void Uniform1iv(WebGLUniformLocation* location,
-                    const dom::Sequence<WebGLint>& arr) {
+                    const dom::Sequence<GLint>& arr) {
         Uniform1iv_base(location, arr.Length(), arr.Elements());
     }
     void Uniform1iv_base(WebGLUniformLocation* location, uint32_t arrayLength,
-                         const WebGLint* data);
+                         const GLint* data);
 
     void Uniform2iv(WebGLUniformLocation* location,
                     const dom::Int32Array& arr) {
         Uniform2iv_base(location, arr.Length(), arr.Data());
     }
     void Uniform2iv(WebGLUniformLocation* location,
-                    const dom::Sequence<WebGLint>& arr) {
+                    const dom::Sequence<GLint>& arr) {
         Uniform2iv_base(location, arr.Length(), arr.Elements());
     }
     void Uniform2iv_base(WebGLUniformLocation* location, uint32_t arrayLength,
-                         const WebGLint* data);
+                         const GLint* data);
 
     void Uniform3iv(WebGLUniformLocation* location,
                     const dom::Int32Array& arr) {
         Uniform3iv_base(location, arr.Length(), arr.Data());
     }
     void Uniform3iv(WebGLUniformLocation* location,
-                    const dom::Sequence<WebGLint>& arr) {
+                    const dom::Sequence<GLint>& arr) {
         Uniform3iv_base(location, arr.Length(), arr.Elements());
     }
     void Uniform3iv_base(WebGLUniformLocation* location, uint32_t arrayLength,
-                         const WebGLint* data);
+                         const GLint* data);
     
     void Uniform4iv(WebGLUniformLocation* location,
                     const dom::Int32Array& arr) {
         Uniform4iv_base(location, arr.Length(), arr.Data());
     }
     void Uniform4iv(WebGLUniformLocation* location,
-                    const dom::Sequence<WebGLint>& arr) {
+                    const dom::Sequence<GLint>& arr) {
         Uniform4iv_base(location, arr.Length(), arr.Elements());
     }
     void Uniform4iv_base(WebGLUniformLocation* location, uint32_t arrayLength,
-                         const WebGLint* data);
+                         const GLint* data);
 
     void Uniform1fv(WebGLUniformLocation* location,
                     const dom::Float32Array& arr) {
         Uniform1fv_base(location, arr.Length(), arr.Data());
     }
     void Uniform1fv(WebGLUniformLocation* location,
-                    const dom::Sequence<WebGLfloat>& arr) {
+                    const dom::Sequence<GLfloat>& arr) {
         Uniform1fv_base(location, arr.Length(), arr.Elements());
     }
     void Uniform1fv_base(WebGLUniformLocation* location, uint32_t arrayLength,
-                         const WebGLfloat* data);
+                         const GLfloat* data);
 
     void Uniform2fv(WebGLUniformLocation* location,
                     const dom::Float32Array& arr) {
         Uniform2fv_base(location, arr.Length(), arr.Data());
     }
     void Uniform2fv(WebGLUniformLocation* location,
-                    const dom::Sequence<WebGLfloat>& arr) {
+                    const dom::Sequence<GLfloat>& arr) {
         Uniform2fv_base(location, arr.Length(), arr.Elements());
     }
     void Uniform2fv_base(WebGLUniformLocation* location, uint32_t arrayLength,
-                         const WebGLfloat* data);
+                         const GLfloat* data);
 
     void Uniform3fv(WebGLUniformLocation* location,
                     const dom::Float32Array& arr) {
         Uniform3fv_base(location, arr.Length(), arr.Data());
     }
     void Uniform3fv(WebGLUniformLocation* location,
-                    const dom::Sequence<WebGLfloat>& arr) {
+                    const dom::Sequence<GLfloat>& arr) {
         Uniform3fv_base(location, arr.Length(), arr.Elements());
     }
     void Uniform3fv_base(WebGLUniformLocation* location, uint32_t arrayLength,
-                         const WebGLfloat* data);
+                         const GLfloat* data);
     
     void Uniform4fv(WebGLUniformLocation* location,
                     const dom::Float32Array& arr) {
         Uniform4fv_base(location, arr.Length(), arr.Data());
     }
     void Uniform4fv(WebGLUniformLocation* location,
-                    const dom::Sequence<WebGLfloat>& arr) {
+                    const dom::Sequence<GLfloat>& arr) {
         Uniform4fv_base(location, arr.Length(), arr.Elements());
     }
     void Uniform4fv_base(WebGLUniformLocation* location, uint32_t arrayLength,
-                         const WebGLfloat* data);
+                         const GLfloat* data);
 
     void UniformMatrix2fv(WebGLUniformLocation* location,
                           WebGLboolean transpose,
                           const dom::Float32Array &value) {
         UniformMatrix2fv_base(location, transpose, value.Length(), value.Data());
     }
     void UniformMatrix2fv(WebGLUniformLocation* location,
                           WebGLboolean transpose,
@@ -709,146 +622,146 @@ public:
     bool ValidateUniformMatrixArraySetter(const char* name, int dim, WebGLUniformLocation *location_object,
                                           GLint& location, uint32_t& numElementsToUpload, uint32_t arrayLength,
                                           WebGLboolean aTranspose);
     bool ValidateUniformSetter(const char* name, WebGLUniformLocation *location_object, GLint& location);
     void ValidateProgram(WebGLProgram *prog);
     bool ValidateUniformLocation(const char* info, WebGLUniformLocation *location_object);
     bool ValidateSamplerUniformSetter(const char* info,
                                     WebGLUniformLocation *location,
-                                    WebGLint value);
+                                    GLint value);
 
-    void Viewport(WebGLint x, WebGLint y, WebGLsizei width, WebGLsizei height);
+    void Viewport(GLint x, GLint y, GLsizei width, GLsizei height);
 
 // -----------------------------------------------------------------------------
 // Asynchronous Queries (WebGLContextAsyncQueries.cpp)
 public:
     already_AddRefed<WebGLQuery> CreateQuery();
     void DeleteQuery(WebGLQuery *query);
-    void BeginQuery(WebGLenum target, WebGLQuery *query);
-    void EndQuery(WebGLenum target);
+    void BeginQuery(GLenum target, WebGLQuery *query);
+    void EndQuery(GLenum target);
     bool IsQuery(WebGLQuery *query);
-    already_AddRefed<WebGLQuery> GetQuery(WebGLenum target, WebGLenum pname);
-    JS::Value GetQueryObject(JSContext* cx, WebGLQuery *query, WebGLenum pname);
+    already_AddRefed<WebGLQuery> GetQuery(GLenum target, GLenum pname);
+    JS::Value GetQueryObject(JSContext* cx, WebGLQuery *query, GLenum pname);
 
 private:
     // ANY_SAMPLES_PASSED(_CONSERVATIVE) slot
     WebGLRefPtr<WebGLQuery> mActiveOcclusionQuery;
 
     // LOCAL_GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN slot
     WebGLRefPtr<WebGLQuery> mActiveTransformFeedbackQuery;
 
-    WebGLRefPtr<WebGLQuery>* GetQueryTargetSlot(WebGLenum target, const char* infos);
+    WebGLRefPtr<WebGLQuery>* GetQueryTargetSlot(GLenum target, const char* infos);
 
 // -----------------------------------------------------------------------------
 // Buffer Objects (WebGLContextBuffers.cpp)
 public:
-    void BindBuffer(WebGLenum target, WebGLBuffer* buf);
-    void BindBufferBase(WebGLenum target, WebGLuint index, WebGLBuffer* buffer);
-    void BindBufferRange(WebGLenum target, WebGLuint index, WebGLBuffer* buffer,
+    void BindBuffer(GLenum target, WebGLBuffer* buf);
+    void BindBufferBase(GLenum target, GLuint index, WebGLBuffer* buffer);
+    void BindBufferRange(GLenum target, GLuint index, WebGLBuffer* buffer,
                          WebGLintptr offset, WebGLsizeiptr size);
-    void BufferData(WebGLenum target, WebGLsizeiptr size, WebGLenum usage);
-    void BufferData(WebGLenum target, const dom::ArrayBufferView &data,
-                    WebGLenum usage);
-    void BufferData(WebGLenum target,
+    void BufferData(GLenum target, WebGLsizeiptr size, GLenum usage);
+    void BufferData(GLenum target, const dom::ArrayBufferView &data,
+                    GLenum usage);
+    void BufferData(GLenum target,
                     const Nullable<dom::ArrayBuffer> &maybeData,
-                    WebGLenum usage);
-    void BufferSubData(WebGLenum target, WebGLsizeiptr byteOffset,
+                    GLenum usage);
+    void BufferSubData(GLenum target, WebGLsizeiptr byteOffset,
                        const dom::ArrayBufferView &data);
-    void BufferSubData(WebGLenum target, WebGLsizeiptr byteOffset,
+    void BufferSubData(GLenum target, WebGLsizeiptr byteOffset,
                        const Nullable<dom::ArrayBuffer> &maybeData);
     already_AddRefed<WebGLBuffer> CreateBuffer();
     void DeleteBuffer(WebGLBuffer *buf);
     bool IsBuffer(WebGLBuffer *buffer);
 
 private:
     // ARRAY_BUFFER slot
     WebGLRefPtr<WebGLBuffer> mBoundArrayBuffer;
 
     // TRANSFORM_FEEDBACK_BUFFER slot
     WebGLRefPtr<WebGLBuffer> mBoundTransformFeedbackBuffer;
 
     // these two functions emit INVALID_ENUM for invalid `target`.
     WebGLRefPtr<WebGLBuffer>* GetBufferSlotByTarget(GLenum target, const char* infos);
     WebGLRefPtr<WebGLBuffer>* GetBufferSlotByTargetIndexed(GLenum target, GLuint index, const char* infos);
-    bool ValidateBufferUsageEnum(WebGLenum target, const char* infos);
+    bool ValidateBufferUsageEnum(GLenum target, const char* infos);
 
 // -----------------------------------------------------------------------------
 // State and State Requests (WebGLContextState.cpp)
 public:
-    void Disable(WebGLenum cap);
-    void Enable(WebGLenum cap);
-    JS::Value GetParameter(JSContext* cx, WebGLenum pname, ErrorResult& rv);
-    JS::Value GetParameterIndexed(JSContext* cx, WebGLenum pname, WebGLuint index);
-    bool IsEnabled(WebGLenum cap);
+    void Disable(GLenum cap);
+    void Enable(GLenum cap);
+    JS::Value GetParameter(JSContext* cx, GLenum pname, ErrorResult& rv);
+    JS::Value GetParameterIndexed(JSContext* cx, GLenum pname, GLuint index);
+    bool IsEnabled(GLenum cap);
 
 private:
     // State tracking slots
     realGLboolean mDitherEnabled;
     realGLboolean mRasterizerDiscardEnabled;
     realGLboolean mScissorTestEnabled;
 
-    bool ValidateCapabilityEnum(WebGLenum cap, const char* info);
-    realGLboolean* GetStateTrackingSlot(WebGLenum cap);
+    bool ValidateCapabilityEnum(GLenum cap, const char* info);
+    realGLboolean* GetStateTrackingSlot(GLenum cap);
 
 // -----------------------------------------------------------------------------
 // Vertices Feature (WebGLContextVertices.cpp)
 public:
-    void DrawArrays(GLenum mode, WebGLint first, WebGLsizei count);
-    void DrawArraysInstanced(GLenum mode, WebGLint first, WebGLsizei count, WebGLsizei primcount);
-    void DrawElements(WebGLenum mode, WebGLsizei count, WebGLenum type, WebGLintptr byteOffset);
-    void DrawElementsInstanced(WebGLenum mode, WebGLsizei count, WebGLenum type,
-                               WebGLintptr byteOffset, WebGLsizei primcount);
+    void DrawArrays(GLenum mode, GLint first, GLsizei count);
+    void DrawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei primcount);
+    void DrawElements(GLenum mode, GLsizei count, GLenum type, WebGLintptr byteOffset);
+    void DrawElementsInstanced(GLenum mode, GLsizei count, GLenum type,
+                               WebGLintptr byteOffset, GLsizei primcount);
 
-    void EnableVertexAttribArray(WebGLuint index);
-    void DisableVertexAttribArray(WebGLuint index);
+    void EnableVertexAttribArray(GLuint index);
+    void DisableVertexAttribArray(GLuint index);
 
-    JS::Value GetVertexAttrib(JSContext* cx, WebGLuint index, WebGLenum pname,
+    JS::Value GetVertexAttrib(JSContext* cx, GLuint index, GLenum pname,
                               ErrorResult& rv);
-    WebGLsizeiptr GetVertexAttribOffset(WebGLuint index, WebGLenum pname);
+    WebGLsizeiptr GetVertexAttribOffset(GLuint index, GLenum pname);
 
-    void VertexAttrib1f(WebGLuint index, WebGLfloat x0);
-    void VertexAttrib2f(WebGLuint index, WebGLfloat x0, WebGLfloat x1);
-    void VertexAttrib3f(WebGLuint index, WebGLfloat x0, WebGLfloat x1,
-                        WebGLfloat x2);
-    void VertexAttrib4f(WebGLuint index, WebGLfloat x0, WebGLfloat x1,
-                        WebGLfloat x2, WebGLfloat x3);
+    void VertexAttrib1f(GLuint index, GLfloat x0);
+    void VertexAttrib2f(GLuint index, GLfloat x0, GLfloat x1);
+    void VertexAttrib3f(GLuint index, GLfloat x0, GLfloat x1,
+                        GLfloat x2);
+    void VertexAttrib4f(GLuint index, GLfloat x0, GLfloat x1,
+                        GLfloat x2, GLfloat x3);
 
-    void VertexAttrib1fv(WebGLuint idx, const dom::Float32Array &arr) {
+    void VertexAttrib1fv(GLuint idx, const dom::Float32Array &arr) {
         VertexAttrib1fv_base(idx, arr.Length(), arr.Data());
     }
-    void VertexAttrib1fv(WebGLuint idx, const dom::Sequence<WebGLfloat>& arr) {
+    void VertexAttrib1fv(GLuint idx, const dom::Sequence<GLfloat>& arr) {
         VertexAttrib1fv_base(idx, arr.Length(), arr.Elements());
     }
 
-    void VertexAttrib2fv(WebGLuint idx, const dom::Float32Array &arr) {
+    void VertexAttrib2fv(GLuint idx, const dom::Float32Array &arr) {
         VertexAttrib2fv_base(idx, arr.Length(), arr.Data());
     }
-    void VertexAttrib2fv(WebGLuint idx, const dom::Sequence<WebGLfloat>& arr) {
+    void VertexAttrib2fv(GLuint idx, const dom::Sequence<GLfloat>& arr) {
         VertexAttrib2fv_base(idx, arr.Length(), arr.Elements());
     }
 
-    void VertexAttrib3fv(WebGLuint idx, const dom::Float32Array &arr) {
+    void VertexAttrib3fv(GLuint idx, const dom::Float32Array &arr) {
         VertexAttrib3fv_base(idx, arr.Length(), arr.Data());
     }
-    void VertexAttrib3fv(WebGLuint idx, const dom::Sequence<WebGLfloat>& arr) {
+    void VertexAttrib3fv(GLuint idx, const dom::Sequence<GLfloat>& arr) {
         VertexAttrib3fv_base(idx, arr.Length(), arr.Elements());
     }
 
-    void VertexAttrib4fv(WebGLuint idx, const dom::Float32Array &arr) {
+    void VertexAttrib4fv(GLuint idx, const dom::Float32Array &arr) {
         VertexAttrib4fv_base(idx, arr.Length(), arr.Data());
     }
-    void VertexAttrib4fv(WebGLuint idx, const dom::Sequence<WebGLfloat>& arr) {
+    void VertexAttrib4fv(GLuint idx, const dom::Sequence<GLfloat>& arr) {
         VertexAttrib4fv_base(idx, arr.Length(), arr.Elements());
     }
 
-    void VertexAttribPointer(WebGLuint index, WebGLint size, WebGLenum type,
-                             WebGLboolean normalized, WebGLsizei stride,
+    void VertexAttribPointer(GLuint index, GLint size, GLenum type,
+                             WebGLboolean normalized, GLsizei stride,
                              WebGLintptr byteOffset);
-    void VertexAttribDivisor(WebGLuint index, WebGLuint divisor);
+    void VertexAttribDivisor(GLuint index, GLuint divisor);
 
 private:
     // Cache the max number of vertices and instances that can be read from
     // bound VBOs (result of ValidateBuffers).
     bool mBufferFetchingIsVerified;
     bool mBufferFetchingHasPerVertex;
     uint32_t mMaxFetchedVertices;
     uint32_t mMaxFetchedInstances;
@@ -856,47 +769,47 @@ private:
     inline void InvalidateBufferFetching()
     {
         mBufferFetchingIsVerified = false;
         mBufferFetchingHasPerVertex = false;
         mMaxFetchedVertices = 0;
         mMaxFetchedInstances = 0;
     }
 
-    bool DrawArrays_check(WebGLint first, WebGLsizei count, WebGLsizei primcount, const char* info);
-    bool DrawElements_check(WebGLsizei count, WebGLenum type, WebGLintptr byteOffset,
-                            WebGLsizei primcount, const char* info);
+    bool DrawArrays_check(GLint first, GLsizei count, GLsizei primcount, const char* info);
+    bool DrawElements_check(GLsizei count, GLenum type, WebGLintptr byteOffset,
+                            GLsizei primcount, const char* info);
     void Draw_cleanup();
 
-    void VertexAttrib1fv_base(WebGLuint idx, uint32_t arrayLength, const WebGLfloat* ptr);
-    void VertexAttrib2fv_base(WebGLuint idx, uint32_t arrayLength, const WebGLfloat* ptr);
-    void VertexAttrib3fv_base(WebGLuint idx, uint32_t arrayLength, const WebGLfloat* ptr);
-    void VertexAttrib4fv_base(WebGLuint idx, uint32_t arrayLength, const WebGLfloat* ptr);
+    void VertexAttrib1fv_base(GLuint idx, uint32_t arrayLength, const GLfloat* ptr);
+    void VertexAttrib2fv_base(GLuint idx, uint32_t arrayLength, const GLfloat* ptr);
+    void VertexAttrib3fv_base(GLuint idx, uint32_t arrayLength, const GLfloat* ptr);
+    void VertexAttrib4fv_base(GLuint idx, uint32_t arrayLength, const GLfloat* ptr);
 
     bool ValidateBufferFetching(const char *info);
     bool BindArrayAttribToLocation0(WebGLProgram *program);
 
 // -----------------------------------------------------------------------------
 // PROTECTED
 protected:
     void SetDontKnowIfNeedFakeBlack() {
         mFakeBlackStatus = DontKnowIfNeedFakeBlack;
     }
 
     bool NeedFakeBlack();
     void BindFakeBlackTextures();
     void UnbindFakeBlackTextures();
 
     int WhatDoesVertexAttrib0Need();
-    bool DoFakeVertexAttrib0(WebGLuint vertexCount);
+    bool DoFakeVertexAttrib0(GLuint vertexCount);
     void UndoFakeVertexAttrib0();
     void InvalidateFakeVertexAttrib0();
 
-    static CheckedUint32 GetImageSize(WebGLsizei height, 
-                                      WebGLsizei width, 
+    static CheckedUint32 GetImageSize(GLsizei height, 
+                                      GLsizei width, 
                                       uint32_t pixelSize,
                                       uint32_t alignment);
 
     // Returns x rounded to the next highest multiple of y.
     static CheckedUint32 RoundedToNextMultipleOf(CheckedUint32 x, CheckedUint32 y) {
         return ((x + y - 1) / y) * y;
     }
 
@@ -917,18 +830,18 @@ protected:
     bool mCanLoseContextInForeground;
     bool mShouldPresent;
     bool mIsScreenCleared;
     bool mDisableFragHighP;
 
     template<typename WebGLObjectType>
     void DeleteWebGLObjectsArray(nsTArray<WebGLObjectType>& array);
 
-    WebGLuint mActiveTexture;
-    WebGLenum mWebGLError;
+    GLuint mActiveTexture;
+    GLenum mWebGLError;
 
     // whether shader validation is supported
     bool mShaderValidation;
 
     // some GL constants
     int32_t mGLMaxVertexAttribs;
     int32_t mGLMaxTextureUnits;
     int32_t mGLMaxTextureSize;
@@ -938,23 +851,24 @@ protected:
     int32_t mGLMaxVertexTextureImageUnits;
     int32_t mGLMaxVaryingVectors;
     int32_t mGLMaxFragmentUniformVectors;
     int32_t mGLMaxVertexUniformVectors;
     int32_t mGLMaxColorAttachments;
     int32_t mGLMaxDrawBuffers;
     uint32_t mGLMaxTransformFeedbackSeparateAttribs;
 
-    // Represents current status, or state, of the context. That is, is it lost
-    // or stable and what part of the context lost process are we currently at.
+    // Represents current status of the context with respect to context loss.
+    // That is, whether the context is lost, and what part of the context loss
+    // process we currently are at.
     // This is used to support the WebGL spec's asyncronous nature in handling
     // context loss.
     enum ContextStatus {
         // The context is stable; there either are none or we don't know of any.
-        ContextStable,
+        ContextNotLost,
         // The context has been lost, but we have not yet sent an event to the
         // script informing it of this.
         ContextLostAwaitingEvent,
         // The context has been lost, and we have sent the script an event
         // informing it of this.
         ContextLost,
         // The context is lost, an event has been sent to the script, and the
         // script correctly handled the event. We are waiting for the context to
@@ -991,75 +905,75 @@ protected:
     bool IsExtensionEnabled(WebGLExtensionID ext) const;
 
     // returns true if the extension is supported for this JSContext (this decides what getSupportedExtensions exposes)
     bool IsExtensionSupported(JSContext *cx, WebGLExtensionID ext) const;
     bool IsExtensionSupported(WebGLExtensionID ext) const;
 
     static const char* GetExtensionString(WebGLExtensionID ext);
 
-    nsTArray<WebGLenum> mCompressedTextureFormats;
+    nsTArray<GLenum> mCompressedTextureFormats;
 
 
     // -------------------------------------------------------------------------
     // WebGL 2 specifics (implemented in WebGL2Context.cpp)
 
     virtual bool IsWebGL2() const = 0;
 
     bool InitWebGL2();
 
 
     // -------------------------------------------------------------------------
     // Validation functions (implemented in WebGLContextValidate.cpp)
     bool InitAndValidateGL();
-    bool ValidateBlendEquationEnum(WebGLenum cap, const char *info);
-    bool ValidateBlendFuncDstEnum(WebGLenum mode, const char *info);
-    bool ValidateBlendFuncSrcEnum(WebGLenum mode, const char *info);
-    bool ValidateBlendFuncEnumsCompatibility(WebGLenum sfactor, WebGLenum dfactor, const char *info);
-    bool ValidateTextureTargetEnum(WebGLenum target, const char *info);
-    bool ValidateComparisonEnum(WebGLenum target, const char *info);
-    bool ValidateStencilOpEnum(WebGLenum action, const char *info);
-    bool ValidateFaceEnum(WebGLenum face, const char *info);
-    bool ValidateTexFormatAndType(WebGLenum format, WebGLenum type, int jsArrayType,
+    bool ValidateBlendEquationEnum(GLenum cap, const char *info);
+    bool ValidateBlendFuncDstEnum(GLenum mode, const char *info);
+    bool ValidateBlendFuncSrcEnum(GLenum mode, const char *info);
+    bool ValidateBlendFuncEnumsCompatibility(GLenum sfactor, GLenum dfactor, const char *info);
+    bool ValidateTextureTargetEnum(GLenum target, const char *info);
+    bool ValidateComparisonEnum(GLenum target, const char *info);
+    bool ValidateStencilOpEnum(GLenum action, const char *info);
+    bool ValidateFaceEnum(GLenum face, const char *info);
+    bool ValidateTexFormatAndType(GLenum format, GLenum type, int jsArrayType,
                                       uint32_t *texelSize, const char *info);
-    bool ValidateDrawModeEnum(WebGLenum mode, const char *info);
-    bool ValidateAttribIndex(WebGLuint index, const char *info);
+    bool ValidateDrawModeEnum(GLenum mode, const char *info);
+    bool ValidateAttribIndex(GLuint index, const char *info);
     bool ValidateStencilParamsForDrawCall();
     
     bool ValidateGLSLVariableName(const nsAString& name, const char *info);
     bool ValidateGLSLCharacter(PRUnichar c);
     bool ValidateGLSLString(const nsAString& string, const char *info);
 
-    bool ValidateTexImage2DTarget(WebGLenum target, WebGLsizei width, WebGLsizei height, const char* info);
-    bool ValidateCompressedTextureSize(WebGLenum target, WebGLint level, WebGLenum format, WebGLsizei width, WebGLsizei height, uint32_t byteLength, const char* info);
-    bool ValidateLevelWidthHeightForTarget(WebGLenum target, WebGLint level, WebGLsizei width, WebGLsizei height, const char* info);
+    bool ValidateTexImage2DTarget(GLenum target, GLsizei width, GLsizei height, const char* info);
+    bool ValidateCompressedTextureSize(GLenum target, GLint level, GLenum format, GLsizei width, GLsizei height, uint32_t byteLength, const char* info);
+    bool ValidateLevelWidthHeightForTarget(GLenum target, GLint level, GLsizei width, GLsizei height, const char* info);
 
-    static uint32_t GetBitsPerTexel(WebGLenum format, WebGLenum type);
+    static uint32_t GetBitsPerTexel(GLenum format, GLenum type);
 
     void Invalidate();
     void DestroyResourcesAndContext();
 
-    void MakeContextCurrent() const { gl->MakeCurrent(); }
+    void MakeContextCurrent() const;
 
     // helpers
-    void TexImage2D_base(WebGLenum target, WebGLint level, WebGLenum internalformat,
-                         WebGLsizei width, WebGLsizei height, WebGLsizei srcStrideOrZero, WebGLint border,
-                         WebGLenum format, WebGLenum type,
+    void TexImage2D_base(GLenum target, GLint level, GLenum internalformat,
+                         GLsizei width, GLsizei height, GLsizei srcStrideOrZero, GLint border,
+                         GLenum format, GLenum type,
                          void *data, uint32_t byteLength,
                          int jsArrayType,
                          WebGLTexelFormat srcFormat, bool srcPremultiplied);
-    void TexSubImage2D_base(WebGLenum target, WebGLint level,
-                            WebGLint xoffset, WebGLint yoffset,
-                            WebGLsizei width, WebGLsizei height, WebGLsizei srcStrideOrZero,
-                            WebGLenum format, WebGLenum type,
+    void TexSubImage2D_base(GLenum target, GLint level,
+                            GLint xoffset, GLint yoffset,
+                            GLsizei width, GLsizei height, GLsizei srcStrideOrZero,
+                            GLenum format, GLenum type,
                             void *pixels, uint32_t byteLength,
                             int jsArrayType,
                             WebGLTexelFormat srcFormat, bool srcPremultiplied);
-    void TexParameter_base(WebGLenum target, WebGLenum pname,
-                           WebGLint *intParamPtr, WebGLfloat *floatParamPtr);
+    void TexParameter_base(GLenum target, GLenum pname,
+                           GLint *intParamPtr, GLfloat *floatParamPtr);
 
     void ConvertImage(size_t width, size_t height, size_t srcStride, size_t dstStride,
                       const uint8_t* src, uint8_t *dst,
                       WebGLTexelFormat srcFormat, bool srcPremultiplied,
                       WebGLTexelFormat dstFormat, bool dstPremultiplied,
                       size_t dstTexelSize);
 
     template<class ElementType>
@@ -1079,25 +993,25 @@ protected:
     {
       return SurfaceFromElement(&aElement);
     }
 
     nsresult SurfaceFromElementResultToImageSurface(nsLayoutUtils::SurfaceFromElementResult& res,
                                                     gfxImageSurface **imageOut,
                                                     WebGLTexelFormat *format);
 
-    void CopyTexSubImage2D_base(WebGLenum target,
-                                WebGLint level,
-                                WebGLenum internalformat,
-                                WebGLint xoffset,
-                                WebGLint yoffset,
-                                WebGLint x,
-                                WebGLint y,
-                                WebGLsizei width,
-                                WebGLsizei height,
+    void CopyTexSubImage2D_base(GLenum target,
+                                GLint level,
+                                GLenum internalformat,
+                                GLint xoffset,
+                                GLint yoffset,
+                                GLint x,
+                                GLint y,
+                                GLsizei width,
+                                GLsizei height,
                                 bool sub);
 
     // Returns false if aObject is null or not valid
     template<class ObjectType>
     bool ValidateObject(const char* info, ObjectType *aObject);
     // Returns false if aObject is not valid.  Considers null to be valid.
     template<class ObjectType>
     bool ValidateObjectAllowNull(const char* info, ObjectType *aObject);
@@ -1111,17 +1025,17 @@ protected:
     bool ValidateObjectAllowDeleted(const char* info, ObjectType *aObject);
 private:
     // Like ValidateObject, but only for cases when aObject is known
     // to not be null already.
     template<class ObjectType>
     bool ValidateObjectAssumeNonNull(const char* info, ObjectType *aObject);
 
 protected:
-    int32_t MaxTextureSizeForTarget(WebGLenum target) const {
+    int32_t MaxTextureSizeForTarget(GLenum target) const {
         return target == LOCAL_GL_TEXTURE_2D ? mGLMaxTextureSize : mGLMaxCubeMapTextureSize;
     }
     
     /** like glBufferData but if the call may change the buffer size, checks any GL error generated
      * by this glBufferData call and returns it */
     GLenum CheckedBufferData(GLenum target,
                              GLsizeiptr size,
                              const GLvoid *data,
@@ -1134,19 +1048,16 @@ protected:
                              GLsizei width,
                              GLsizei height,
                              GLint border,
                              GLenum format,
                              GLenum type,
                              const GLvoid *data);
 
     void MaybeRestoreContext();
-    bool IsContextStable() const {
-        return mContextStatus == ContextStable;
-    }
     void ForceLoseContext();
     void ForceRestoreContext();
 
     nsTArray<WebGLRefPtr<WebGLTexture> > mBound2DTextures;
     nsTArray<WebGLRefPtr<WebGLTexture> > mBoundCubeMapTextures;
 
     WebGLRefPtr<WebGLProgram> mCurrentProgram;
 
@@ -1168,68 +1079,62 @@ protected:
     WebGLRefPtr<WebGLVertexArray> mDefaultVertexArray;
 
     // PixelStore parameters
     uint32_t mPixelStorePackAlignment, mPixelStoreUnpackAlignment, mPixelStoreColorspaceConversion;
     bool mPixelStoreFlipY, mPixelStorePremultiplyAlpha;
 
     FakeBlackStatus mFakeBlackStatus;
 
-    WebGLuint mBlackTexture2D, mBlackTextureCubeMap;
+    GLuint mBlackTexture2D, mBlackTextureCubeMap;
     bool mBlackTexturesAreInitialized;
 
-    WebGLfloat mVertexAttrib0Vector[4];
-    WebGLfloat mFakeVertexAttrib0BufferObjectVector[4];
+    GLfloat mVertexAttrib0Vector[4];
+    GLfloat mFakeVertexAttrib0BufferObjectVector[4];
     size_t mFakeVertexAttrib0BufferObjectSize;
     GLuint mFakeVertexAttrib0BufferObject;
     int mFakeVertexAttrib0BufferStatus;
 
-    WebGLint mStencilRefFront, mStencilRefBack;
-    WebGLuint mStencilValueMaskFront, mStencilValueMaskBack,
+    GLint mStencilRefFront, mStencilRefBack;
+    GLuint mStencilValueMaskFront, mStencilValueMaskBack,
               mStencilWriteMaskFront, mStencilWriteMaskBack;
     realGLboolean mColorWriteMask[4];
     realGLboolean mDepthWriteMask;
-    WebGLfloat mColorClearValue[4];
-    WebGLint mStencilClearValue;
-    WebGLfloat mDepthClearValue;
+    GLfloat mColorClearValue[4];
+    GLint mStencilClearValue;
+    GLfloat mDepthClearValue;
 
     nsCOMPtr<nsITimer> mContextRestorer;
     bool mAllowRestore;
     bool mContextLossTimerRunning;
     bool mDrawSinceContextLossTimerSet;
     ContextStatus mContextStatus;
     bool mContextLostErrorSet;
 
     // Used for some hardware (particularly Tegra 2 and 4) that likes to
     // be Flushed while doing hundreds of draw calls.
     int mDrawCallsSinceLastFlush;
 
     int mAlreadyGeneratedWarnings;
     int mMaxWarnings;
     bool mAlreadyWarnedAboutFakeVertexAttrib0;
 
-    bool ShouldGenerateWarnings() const {
-        if (mMaxWarnings == -1) {
-            return true;
-        }
-
-        return mAlreadyGeneratedWarnings < mMaxWarnings;
-    }
+    bool ShouldGenerateWarnings() const;
 
     uint64_t mLastUseIndex;
 
     void LoseOldestWebGLContextIfLimitExceeded();
     void UpdateLastUseIndex();
 
     template <typename WebGLObjectType>
     JS::Value WebGLObjectAsJSValue(JSContext *cx, const WebGLObjectType *, ErrorResult& rv) const;
     template <typename WebGLObjectType>
     JSObject* WebGLObjectAsJSObject(JSContext *cx, const WebGLObjectType *, ErrorResult& rv) const;
 
-    void ReattachTextureToAnyFramebufferToWorkAroundBugs(WebGLTexture *tex, WebGLint level);
+    void ReattachTextureToAnyFramebufferToWorkAroundBugs(WebGLTexture *tex, GLint level);
 
 #ifdef XP_MACOSX
     // see bug 713305. This RAII helper guarantees that we're on the discrete GPU, during its lifetime
     // Debouncing note: we don't want to switch GPUs too frequently, so try to not create and destroy
     // these objects at high frequency. Having WebGLContext's hold one such object seems fine,
     // because WebGLContext objects only go away during GC, which shouldn't happen too frequently.
     // If in the future GC becomes much more frequent, we may have to revisit then (maybe use a timer).
     ForceDiscreteGPUHelperCGL mForceDiscreteGPUHelper;
--- a/content/canvas/src/WebGLContextAsyncQueries.cpp
+++ b/content/canvas/src/WebGLContextAsyncQueries.cpp
@@ -1,30 +1,31 @@
 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
 /* 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/. */
 
 #include "WebGLContext.h"
 #include "WebGLQuery.h"
+#include "GLContext.h"
 
 using namespace mozilla;
 
 /*
  * We fake ANY_SAMPLES_PASSED and ANY_SAMPLES_PASSED_CONSERVATIVE with
  * SAMPLES_PASSED on desktop.
  *
  * OpenGL ES 3.0 spec 4.1.6
  *  If the target of the query is ANY_SAMPLES_PASSED_CONSERVATIVE, an implementation
  *  may choose to use a less precise version of the test which can additionally set
  *  the samples-boolean state to TRUE in some other implementation-dependent cases.
  */
 
 static const char*
-GetQueryTargetEnumString(WebGLenum target)
+GetQueryTargetEnumString(GLenum target)
 {
     switch (target)
     {
         case LOCAL_GL_ANY_SAMPLES_PASSED:
             return "ANY_SAMPLES_PASSED";
         case LOCAL_GL_ANY_SAMPLES_PASSED_CONSERVATIVE:
             return "ANY_SAMPLES_PASSED_CONSERVATIVE";
         case LOCAL_GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN:
@@ -51,17 +52,17 @@ SimulateOcclusionQueryTarget(const gl::G
     }
 
     return LOCAL_GL_SAMPLES_PASSED;
 }
 
 already_AddRefed<WebGLQuery>
 WebGLContext::CreateQuery()
 {
-    if (!IsContextStable())
+    if (IsContextLost())
         return nullptr;
 
     if (mActiveOcclusionQuery && !gl->IsGLES2()) {
         /* http://www.opengl.org/registry/specs/ARB/occlusion_query.txt
          * Calling either GenQueriesARB or DeleteQueriesARB while any query of
          * any target is active causes an INVALID_OPERATION error to be
          * generated.
          */
@@ -76,17 +77,17 @@ WebGLContext::CreateQuery()
     nsRefPtr<WebGLQuery> globj = new WebGLQuery(this);
 
     return globj.forget();
 }
 
 void
 WebGLContext::DeleteQuery(WebGLQuery *query)
 {
-    if (!IsContextStable())
+    if (IsContextLost())
         return;
 
     if (!query)
         return;
 
     if (query->IsDeleted())
         return;
 
@@ -103,19 +104,19 @@ WebGLContext::DeleteQuery(WebGLQuery *qu
         GenerateWarning("deleteQuery: the WebGL 2 prototype might generate INVALID_OPERATION"
                         "when deleting a query object while one other is active.");
     }
 
     query->RequestDelete();
 }
 
 void
-WebGLContext::BeginQuery(WebGLenum target, WebGLQuery *query)
+WebGLContext::BeginQuery(GLenum target, WebGLQuery *query)
 {
-    if (!IsContextStable())
+    if (IsContextLost())
         return;
 
     WebGLRefPtr<WebGLQuery>* targetSlot = GetQueryTargetSlot(target, "beginQuery");
     if (!targetSlot) {
         return;
     }
 
     if (!query) {
@@ -173,19 +174,19 @@ WebGLContext::BeginQuery(WebGLenum targe
     } else {
         gl->fBeginQuery(SimulateOcclusionQueryTarget(gl, target), query->mGLName);
     }
 
     *targetSlot = query;
 }
 
 void
-WebGLContext::EndQuery(WebGLenum target)
+WebGLContext::EndQuery(GLenum target)
 {
-    if (!IsContextStable())
+    if (IsContextLost())
         return;
 
     WebGLRefPtr<WebGLQuery>* targetSlot = GetQueryTargetSlot(target, "endQuery");
     if (!targetSlot) {
         return;
     }
 
     if (!*targetSlot ||
@@ -217,31 +218,31 @@ WebGLContext::EndQuery(WebGLenum target)
     }
 
     *targetSlot = nullptr;
 }
 
 bool
 WebGLContext::IsQuery(WebGLQuery *query)
 {
-    if (!IsContextStable())
+    if (IsContextLost())
         return false;
 
     if (!query)
         return false;
 
     return ValidateObjectAllowDeleted("isQuery", query) &&
            !query->IsDeleted() &&
            query->HasEverBeenActive();
 }
 
 already_AddRefed<WebGLQuery>
-WebGLContext::GetQuery(WebGLenum target, WebGLenum pname)
+WebGLContext::GetQuery(GLenum target, GLenum pname)
 {
-    if (!IsContextStable())
+    if (IsContextLost())
         return nullptr;
 
     WebGLRefPtr<WebGLQuery>* targetSlot = GetQueryTargetSlot(target, "getQuery");
     if (!targetSlot) {
         return nullptr;
     }
 
     if (pname != LOCAL_GL_CURRENT_QUERY) {
@@ -252,19 +253,19 @@ WebGLContext::GetQuery(WebGLenum target,
         return nullptr;
     }
 
     nsRefPtr<WebGLQuery> tmp = targetSlot->get();
     return tmp.forget();
 }
 
 JS::Value
-WebGLContext::GetQueryObject(JSContext* cx, WebGLQuery *query, WebGLenum pname)
+WebGLContext::GetQueryObject(JSContext* cx, WebGLQuery *query, GLenum pname)
 {
-    if (!IsContextStable())
+    if (IsContextLost())
         return JS::NullValue();
 
     if (!query) {
         /* OpenGL ES 3.0 spec 6.1.7 (spec getQueryObject 1)
          *  If id is not the name of a query object, or if the query object named by id is
          *  currently active, then an INVALID_OPERATION error is generated. pname must be
          *  QUERY_RESULT or QUERY_RESULT_AVAILABLE.
          */
@@ -328,17 +329,17 @@ WebGLContext::GetQueryObject(JSContext* 
             break;
     }
 
     ErrorInvalidEnum("getQueryObject: pname must be QUERY_RESULT{_AVAILABLE}");
     return JS::NullValue();
 }
 
 WebGLRefPtr<WebGLQuery>*
-WebGLContext::GetQueryTargetSlot(WebGLenum target, const char* infos)
+WebGLContext::GetQueryTargetSlot(GLenum target, const char* infos)
 {
     switch (target) {
         case LOCAL_GL_ANY_SAMPLES_PASSED:
         case LOCAL_GL_ANY_SAMPLES_PASSED_CONSERVATIVE:
             return &mActiveOcclusionQuery;
         case LOCAL_GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN:
             return &mActiveTransformFeedbackQuery;
     }
--- a/content/canvas/src/WebGLContextBuffers.cpp
+++ b/content/canvas/src/WebGLContextBuffers.cpp
@@ -1,24 +1,25 @@
 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
 /* 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/. */
 
 #include "WebGLContext.h"
+#include "GLContext.h"
 #include "WebGLBuffer.h"
 #include "WebGLVertexArray.h"
 
 using namespace mozilla;
 using namespace mozilla::dom;
 
 void
-WebGLContext::BindBuffer(WebGLenum target, WebGLBuffer *buffer)
+WebGLContext::BindBuffer(GLenum target, WebGLBuffer *buffer)
 {
-    if (!IsContextStable())
+    if (IsContextLost())
         return;
 
     if (!ValidateObjectAllowDeletedOrNull("bindBuffer", buffer))
         return;
 
     // silently ignore a deleted buffer
     if (buffer && buffer->IsDeleted())
         return;
@@ -41,19 +42,19 @@ WebGLContext::BindBuffer(WebGLenum targe
     *bufferSlot = buffer;
 
     MakeContextCurrent();
 
     gl->fBindBuffer(target, buffer ? buffer->GLName() : 0);
 }
 
 void
-WebGLContext::BindBufferBase(WebGLenum target, WebGLuint index, WebGLBuffer* buffer)
+WebGLContext::BindBufferBase(GLenum target, GLuint index, WebGLBuffer* buffer)
 {
-    if (!IsContextStable())
+    if (IsContextLost())
         return;
 
     if (!ValidateObjectAllowDeletedOrNull("bindBufferBase", buffer))
         return;
 
     // silently ignore a deleted buffer
     if (buffer && buffer->IsDeleted()) {
         return;
@@ -82,20 +83,20 @@ WebGLContext::BindBufferBase(WebGLenum t
     *bufferSlot = buffer;
 
     MakeContextCurrent();
 
     gl->fBindBufferBase(target, index, buffer ? buffer->GLName() : 0);
 }
 
 void
-WebGLContext::BindBufferRange(WebGLenum target, WebGLuint index, WebGLBuffer* buffer,
+WebGLContext::BindBufferRange(GLenum target, GLuint index, WebGLBuffer* buffer,
                               WebGLintptr offset, WebGLsizeiptr size)
 {
-    if (!IsContextStable())
+    if (IsContextLost())
         return;
 
     if (!ValidateObjectAllowDeletedOrNull("bindBufferRange", buffer))
         return;
 
     // silently ignore a deleted buffer
     if (buffer && buffer->IsDeleted())
         return;
@@ -108,49 +109,59 @@ WebGLContext::BindBufferRange(WebGLenum 
 
     if (buffer) {
         if (!buffer->Target()) {
             buffer->SetTarget(target);
             buffer->SetHasEverBeenBound(true);
         } else if (target != buffer->Target()) {
             return ErrorInvalidOperation("bindBuffer: buffer already bound to a different target");
         }
+        CheckedInt<WebGLsizeiptr> checked_neededByteLength = CheckedInt<WebGLsizeiptr>(offset) + size;
+        if (!checked_neededByteLength.isValid() ||
+            checked_neededByteLength.value() > buffer->ByteLength())
+        {
+            return ErrorInvalidValue("bindBufferRange: invalid range");
+        }
     }
 
     WebGLRefPtr<WebGLBuffer>* bufferSlot = GetBufferSlotByTarget(target, "bindBuffer");
 
     MOZ_ASSERT(bufferSlot, "GetBufferSlotByTarget(Indexed) mismatch");
 
     *indexedBufferSlot = buffer;
     *bufferSlot = buffer;
 
     MakeContextCurrent();
 
     gl->fBindBufferRange(target, index, buffer ? buffer->GLName() : 0, offset, size);
 }
 
 void
-WebGLContext::BufferData(WebGLenum target, WebGLsizeiptr size,
-                         WebGLenum usage)
+WebGLContext::BufferData(GLenum target, WebGLsizeiptr size,
+                         GLenum usage)
 {
-    if (!IsContextStable())
+    if (IsContextLost())
         return;
 
     WebGLRefPtr<WebGLBuffer>* bufferSlot = GetBufferSlotByTarget(target, "bufferData");
 
     if (!bufferSlot) {
         return;
     }
 
     if (size < 0)
         return ErrorInvalidValue("bufferData: negative size");
 
     if (!ValidateBufferUsageEnum(usage, "bufferData: usage"))
         return;
 
+    // careful: WebGLsizeiptr is always 64-bit, but GLsizeiptr is like intptr_t.
+    if (!CheckedInt<GLsizeiptr>(size).isValid())
+        return ErrorOutOfMemory("bufferData: bad size");
+
     WebGLBuffer* boundBuffer = bufferSlot->get();
 
     if (!boundBuffer)
         return ErrorInvalidOperation("bufferData: no buffer bound!");
 
     void* zeroBuffer = calloc(size, 1);
     if (!zeroBuffer)
         return ErrorOutOfMemory("bufferData: out of memory");
@@ -168,36 +179,40 @@ WebGLContext::BufferData(WebGLenum targe
 
     boundBuffer->SetByteLength(size);
     if (!boundBuffer->ElementArrayCacheBufferData(nullptr, size)) {
         return ErrorOutOfMemory("bufferData: out of memory");
     }
 }
 
 void
-WebGLContext::BufferData(WebGLenum target,
+WebGLContext::BufferData(GLenum target,
                          const Nullable<ArrayBuffer> &maybeData,
-                         WebGLenum usage)
+                         GLenum usage)
 {
-    if (!IsContextStable())
+    if (IsContextLost())
         return;
 
     if (maybeData.IsNull()) {
         // see http://www.khronos.org/bugzilla/show_bug.cgi?id=386
         return ErrorInvalidValue("bufferData: null object passed");
     }
 
     WebGLRefPtr<WebGLBuffer>* bufferSlot = GetBufferSlotByTarget(target, "bufferData");
 
     if (!bufferSlot) {
         return;
     }
 
     const ArrayBuffer& data = maybeData.Value();
 
+    // careful: data.Length() could conceivably be any size_t, but GLsizeiptr is like intptr_t.
+    if (!CheckedInt<GLsizeiptr>(data.Length()).isValid())
+        return ErrorOutOfMemory("bufferData: bad size");
+
     if (!ValidateBufferUsageEnum(usage, "bufferData: usage"))
         return;
 
     WebGLBuffer* boundBuffer = bufferSlot->get();
 
     if (!boundBuffer)
         return ErrorInvalidOperation("bufferData: no buffer bound!");
 
@@ -213,36 +228,40 @@ WebGLContext::BufferData(WebGLenum targe
 
     boundBuffer->SetByteLength(data.Length());
     if (!boundBuffer->ElementArrayCacheBufferData(data.Data(), data.Length())) {
         return ErrorOutOfMemory("bufferData: out of memory");
     }
 }
 
 void
-WebGLContext::BufferData(WebGLenum target, const ArrayBufferView& data,
-                         WebGLenum usage)
+WebGLContext::BufferData(GLenum target, const ArrayBufferView& data,
+                         GLenum usage)
 {
-    if (!IsContextStable())
+    if (IsContextLost())
         return;
 
     WebGLRefPtr<WebGLBuffer>* bufferSlot = GetBufferSlotByTarget(target, "bufferSubData");
 
     if (!bufferSlot) {
         return;
     }
 
     if (!ValidateBufferUsageEnum(usage, "bufferData: usage"))
         return;
 
     WebGLBuffer* boundBuffer = bufferSlot->get();
 
     if (!boundBuffer)
         return ErrorInvalidOperation("bufferData: no buffer bound!");
 
+    // careful: data.Length() could conceivably be any size_t, but GLsizeiptr is like intptr_t.
+    if (!CheckedInt<GLsizeiptr>(data.Length()).isValid())
+        return ErrorOutOfMemory("bufferData: bad size");
+
     InvalidateBufferFetching();
     MakeContextCurrent();
 
     GLenum error = CheckedBufferData(target, data.Length(), data.Data(), usage);
     if (error) {
         GenerateWarning("bufferData generated error %s", ErrorName(error));
         return;
     }
@@ -252,17 +271,17 @@ WebGLContext::BufferData(WebGLenum targe
         return ErrorOutOfMemory("bufferData: out of memory");
     }
 }
 
 void
 WebGLContext::BufferSubData(GLenum target, WebGLsizeiptr byteOffset,
                             const Nullable<ArrayBuffer> &maybeData)
 {
-    if (!IsContextStable())
+    if (IsContextLost())
         return;
 
     if (maybeData.IsNull()) {
         // see http://www.khronos.org/bugzilla/show_bug.cgi?id=386
         return;
     }
 
     WebGLRefPtr<WebGLBuffer>* bufferSlot = GetBufferSlotByTarget(target, "bufferSubData");
@@ -276,80 +295,80 @@ WebGLContext::BufferSubData(GLenum targe
     if (byteOffset < 0)
         return ErrorInvalidValue("bufferSubData: negative offset");
 
     WebGLBuffer* boundBuffer = bufferSlot->get();
 
     if (!boundBuffer)
         return ErrorInvalidOperation("bufferData: no buffer bound!");
 
-    CheckedUint32 checked_neededByteLength = CheckedUint32(byteOffset) + data.Length();
+    CheckedInt<WebGLsizeiptr> checked_neededByteLength = CheckedInt<WebGLsizeiptr>(byteOffset) + data.Length();
     if (!checked_neededByteLength.isValid())
         return ErrorInvalidValue("bufferSubData: integer overflow computing the needed byte length");
 
     if (checked_neededByteLength.value() > boundBuffer->ByteLength())
         return ErrorInvalidValue("bufferSubData: not enough data - operation requires %d bytes, but buffer only has %d bytes",
                                  checked_neededByteLength.value(), boundBuffer->ByteLength());
 
     MakeContextCurrent();
 
     boundBuffer->ElementArrayCacheBufferSubData(byteOffset, data.Data(), data.Length());
 
     gl->fBufferSubData(target, byteOffset, data.Length(), data.Data());
 }
 
 void
-WebGLContext::BufferSubData(WebGLenum target, WebGLsizeiptr byteOffset,
+WebGLContext::BufferSubData(GLenum target, WebGLsizeiptr byteOffset,
                             const ArrayBufferView& data)
 {
-    if (!IsContextStable())
+    if (IsContextLost())
         return;
 
     WebGLRefPtr<WebGLBuffer>* bufferSlot = GetBufferSlotByTarget(target, "bufferSubData");
 
     if (!bufferSlot) {
         return;
     }
 
     if (byteOffset < 0)
         return ErrorInvalidValue("bufferSubData: negative offset");
 
     WebGLBuffer* boundBuffer = bufferSlot->get();
 
     if (!boundBuffer)
         return ErrorInvalidOperation("bufferSubData: no buffer bound!");
 
-    CheckedUint32 checked_neededByteLength = CheckedUint32(byteOffset) + data.Length();
+    CheckedInt<WebGLsizeiptr> checked_neededByteLength = CheckedInt<WebGLsizeiptr>(byteOffset) + data.Length();
     if (!checked_neededByteLength.isValid())
         return ErrorInvalidValue("bufferSubData: integer overflow computing the needed byte length");
 
     if (checked_neededByteLength.value() > boundBuffer->ByteLength())
         return ErrorInvalidValue("bufferSubData: not enough data -- operation requires %d bytes, but buffer only has %d bytes",
                                  checked_neededByteLength.value(), boundBuffer->ByteLength());
 
     boundBuffer->ElementArrayCacheBufferSubData(byteOffset, data.Data(), data.Length());
 
     MakeContextCurrent();
     gl->fBufferSubData(target, byteOffset, data.Length(), data.Data());
 }
 
 already_AddRefed<WebGLBuffer>
 WebGLContext::CreateBuffer()
 {
-    if (!IsContextStable())
+    if (IsContextLost())
         return nullptr;
 
     nsRefPtr<WebGLBuffer> globj = new WebGLBuffer(this);
     return globj.forget();
 }
 
 void
 WebGLContext::DeleteBuffer(WebGLBuffer *buffer)
 {
-    if (!IsContextStable())
+    if (IsContextLost())
         return;
 
     if (!ValidateObjectAllowDeletedOrNull("deleteBuffer", buffer))
         return;
 
     if (!buffer || buffer->IsDeleted())
         return;
 
@@ -369,26 +388,26 @@ WebGLContext::DeleteBuffer(WebGLBuffer *
     }
 
     buffer->RequestDelete();
 }
 
 bool
 WebGLContext::IsBuffer(WebGLBuffer *buffer)
 {
-    if (!IsContextStable())
+    if (IsContextLost())
         return false;
 
     return ValidateObjectAllowDeleted("isBuffer", buffer) &&
            !buffer->IsDeleted() &&
            buffer->HasEverBeenBound();
 }
 
 bool
-WebGLContext::ValidateBufferUsageEnum(WebGLenum target, const char *infos)
+WebGLContext::ValidateBufferUsageEnum(GLenum target, const char *infos)
 {
     switch (target) {
         case LOCAL_GL_STREAM_DRAW:
         case LOCAL_GL_STATIC_DRAW:
         case LOCAL_GL_DYNAMIC_DRAW:
             return true;
         default:
             break;
@@ -435,8 +454,44 @@ WebGLContext::GetBufferSlotByTargetIndex
 
         default:
             break;
     }
 
     ErrorInvalidEnum("%s: target: invalid enum value 0x%x", infos, target);
     return nullptr;
 }
+
+GLenum
+WebGLContext::CheckedBufferData(GLenum target,
+                                GLsizeiptr size,
+                                const GLvoid *data,
+                                GLenum usage)
+{
+#ifdef XP_MACOSX
+    // bug 790879
+    if (gl->WorkAroundDriverBugs() &&
+        int64_t(size) > INT32_MAX) // the cast avoids a potential always-true warning on 32bit
+    {
+        GenerateWarning("Rejecting valid bufferData call with size %lu to avoid a Mac bug", size);
+        return LOCAL_GL_INVALID_VALUE;
+    }
+#endif
+    WebGLBuffer *boundBuffer = nullptr;
+    if (target == LOCAL_GL_ARRAY_BUFFER) {
+        boundBuffer = mBoundArrayBuffer;
+    } else if (target == LOCAL_GL_ELEMENT_ARRAY_BUFFER) {
+        boundBuffer = mBoundVertexArray->mBoundElementArrayBuffer;
+    }
+    NS_ABORT_IF_FALSE(boundBuffer != nullptr, "no buffer bound for this target");
+
+    bool sizeChanges = uint32_t(size) != boundBuffer->ByteLength();
+    if (sizeChanges) {
+        UpdateWebGLErrorAndClearGLError();
+        gl->fBufferData(target, size, data, usage);
+        GLenum error = LOCAL_GL_NO_ERROR;
+        UpdateWebGLErrorAndClearGLError(&error);
+        return error;
+    } else {
+        gl->fBufferData(target, size, data, usage);
+        return LOCAL_GL_NO_ERROR;
+    }
+}
--- a/content/canvas/src/WebGLContextExtensions.cpp
+++ b/content/canvas/src/WebGLContextExtensions.cpp
@@ -131,17 +131,17 @@ static bool
 CompareWebGLExtensionName(const nsACString& name, const char *other)
 {
     return name.Equals(other, nsCaseInsensitiveCStringComparator());
 }
 
 JSObject*
 WebGLContext::GetExtension(JSContext *cx, const nsAString& aName, ErrorResult& rv)
 {
-    if (!IsContextStable())
+    if (IsContextLost())
         return nullptr;
 
     NS_LossyConvertUTF16toASCII name(aName);
 
     WebGLExtensionID ext = WebGLExtensionID_unknown_extension;
 
     // step 1: figure what extension is wanted
     for (size_t i = 0; i < size_t(WebGLExtensionID_max); i++)
@@ -252,17 +252,17 @@ WebGLContext::EnableExtension(WebGLExten
 
     mExtensions[ext] = obj;
 }
 
 void
 WebGLContext::GetSupportedExtensions(JSContext *cx, Nullable< nsTArray<nsString> > &retval)
 {
     retval.SetNull();
-    if (!IsContextStable())
+    if (IsContextLost())
         return;
 
     nsTArray<nsString>& arr = retval.SetValue();
 
     for (size_t i = 0; i < size_t(WebGLExtensionID_max); i++)
     {
         WebGLExtensionID extension = WebGLExtensionID(i);
 
--- a/content/canvas/src/WebGLContextFramebufferOperations.cpp
+++ b/content/canvas/src/WebGLContextFramebufferOperations.cpp
@@ -2,23 +2,24 @@
 /* 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/. */
 
 #include "WebGLContext.h"
 #include "WebGLTexture.h"
 #include "WebGLRenderbuffer.h"
 #include "WebGLFramebuffer.h"
+#include "GLContext.h"
 
 using namespace mozilla;
 
 void
-WebGLContext::Clear(WebGLbitfield mask)
+WebGLContext::Clear(GLbitfield mask)
 {
-    if (!IsContextStable())
+    if (IsContextLost())
         return;
 
     MakeContextCurrent();
 
     uint32_t m = mask & (LOCAL_GL_COLOR_BUFFER_BIT | LOCAL_GL_DEPTH_BUFFER_BIT | LOCAL_GL_STENCIL_BUFFER_BIT);
     if (mask != m)
         return ErrorInvalidValue("clear: invalid mask bits");
 
@@ -71,83 +72,83 @@ WebGLContext::Clear(WebGLbitfield mask)
         gl->fClear(mask);
         mIsScreenCleared = false;
     }
 
     Invalidate();
     mShouldPresent = true;
 }
 
-static WebGLclampf
-GLClampFloat(WebGLclampf val)
+static GLclampf
+GLClampFloat(GLclampf val)
 {
     if (val < 0.0)
         return 0.0;
 
     if (val > 1.0)
         return 1.0;
 
     return val;
 }
 
 void
-WebGLContext::ClearColor(WebGLclampf r, WebGLclampf g,
-                             WebGLclampf b, WebGLclampf a)
+WebGLContext::ClearColor(GLclampf r, GLclampf g,
+                             GLclampf b, GLclampf a)
 {
-    if (!IsContextStable())
+    if (IsContextLost())
         return;
 
     MakeContextCurrent();
     mColorClearValue[0] = GLClampFloat(r);
     mColorClearValue[1] = GLClampFloat(g);
     mColorClearValue[2] = GLClampFloat(b);
     mColorClearValue[3] = GLClampFloat(a);
     gl->fClearColor(r, g, b, a);
 }
 
 void
-WebGLContext::ClearDepth(WebGLclampf v)
+WebGLContext::ClearDepth(GLclampf v)
 {
-    if (!IsContextStable())
+    if (IsContextLost())
         return;
 
     MakeContextCurrent();
     mDepthClearValue = GLClampFloat(v);
     gl->fClearDepth(v);
 }
 
 void
-WebGLContext::ClearStencil(WebGLint v)
+WebGLContext::ClearStencil(GLint v)
 {
-    if (!IsContextStable())
+    if (IsContextLost())
         return;
 
     MakeContextCurrent();
     mStencilClearValue = v;
     gl->fClearStencil(v);
 }
 
 void
 WebGLContext::ColorMask(WebGLboolean r, WebGLboolean g, WebGLboolean b, WebGLboolean a)
 {
-    if (!IsContextStable())
+    if (IsContextLost())
         return;
 
     MakeContextCurrent();
     mColorWriteMask[0] = r;
     mColorWriteMask[1] = g;
     mColorWriteMask[2] = b;
     mColorWriteMask[3] = a;
     gl->fColorMask(r, g, b, a);
 }
 
 void
 WebGLContext::DepthMask(WebGLboolean b)
 {
-    if (!IsContextStable())
+    if (IsContextLost())
         return;
 
     MakeContextCurrent();
     mDepthWriteMask = b;
     gl->fDepthMask(b);
 }
 
 void
@@ -222,32 +223,32 @@ WebGLContext::DrawBuffers(const dom::Seq
     }
 
     MakeContextCurrent();
 
     gl->fDrawBuffers(buffersLength, buffers.Elements());
 }
 
 void
-WebGLContext::StencilMask(WebGLuint mask)
+WebGLContext::StencilMask(GLuint mask)
 {
-    if (!IsContextStable())
+    if (IsContextLost())
         return;
 
     mStencilWriteMaskFront = mask;
     mStencilWriteMaskBack = mask;
 
     MakeContextCurrent();
     gl->fStencilMask(mask);
 }
 
 void
-WebGLContext::StencilMaskSeparate(WebGLenum face, WebGLuint mask)
+WebGLContext::StencilMaskSeparate(GLenum face, GLuint mask)
 {
-    if (!IsContextStable())
+    if (IsContextLost())
         return;
 
     if (!ValidateFaceEnum(face, "stencilMaskSeparate: face"))
         return;
 
     switch (face) {
         case LOCAL_GL_FRONT_AND_BACK:
             mStencilWriteMaskFront = mask;
--- a/content/canvas/src/WebGLContextGL.cpp
+++ b/content/canvas/src/WebGLContextGL.cpp
@@ -18,16 +18,17 @@
 #include "WebGLVertexArray.h"
 
 #include "nsString.h"
 #include "nsDebug.h"
 
 #include "gfxImageSurface.h"
 #include "gfxContext.h"
 #include "gfxPlatform.h"
+#include "GLContext.h"
 
 #include "nsContentUtils.h"
 #include "nsError.h"
 #include "nsLayoutUtils.h"
 
 #include "CanvasUtils.h"
 
 #include "jsfriendapi.h"
@@ -43,32 +44,32 @@
 
 #include "mozilla/dom/BindingUtils.h"
 #include "mozilla/dom/ImageData.h"
 
 using namespace mozilla;
 using namespace mozilla::dom;
 using namespace mozilla::gl;
 
-static bool BaseTypeAndSizeFromUniformType(WebGLenum uType, WebGLenum *baseType, WebGLint *unitSize);
-static WebGLenum InternalFormatForFormatAndType(WebGLenum format, WebGLenum type, bool isGLES2);
+static bool BaseTypeAndSizeFromUniformType(GLenum uType, GLenum *baseType, GLint *unitSize);
+static GLenum InternalFormatForFormatAndType(GLenum format, GLenum type, bool isGLES2);
 
 //
 //  WebGL API
 //
 
 inline const WebGLRectangleObject *WebGLContext::FramebufferRectangleObject() const {
     return mBoundFramebuffer ? mBoundFramebuffer->RectangleObject()
                              : static_cast<const WebGLRectangleObject*>(this);
 }
 
 void
-WebGLContext::ActiveTexture(WebGLenum texture)
+WebGLContext::ActiveTexture(GLenum texture)
 {
-    if (!IsContextStable()) 
+    if (IsContextLost()) 
         return;
 
     if (texture < LOCAL_GL_TEXTURE0 ||
         texture >= LOCAL_GL_TEXTURE0 + uint32_t(mGLMaxTextureUnits))
     {
         return ErrorInvalidEnum(
             "ActiveTexture: texture unit %d out of range. "
             "Accepted values range from TEXTURE0 to TEXTURE0 + %d. "
@@ -79,17 +80,17 @@ WebGLContext::ActiveTexture(WebGLenum te
     MakeContextCurrent();
     mActiveTexture = texture - LOCAL_GL_TEXTURE0;
     gl->fActiveTexture(texture);
 }
 
 void
 WebGLContext::AttachShader(WebGLProgram *program, WebGLShader *shader)
 {
-    if (!IsContextStable())
+    if (IsContextLost())
         return;
 
     if (!ValidateObject("attachShader: program", program) ||
         !ValidateObject("attachShader: shader", shader))
         return;
 
     // Per GLSL ES 2.0, we can only have one of each type of shader
     // attached.  This renders the next test somewhat moot, but we'll
@@ -98,45 +99,45 @@ WebGLContext::AttachShader(WebGLProgram 
         return ErrorInvalidOperation("attachShader: only one of each type of shader may be attached to a program");
 
     if (!program->AttachShader(shader))
         return ErrorInvalidOperation("attachShader: shader is already attached");
 }
 
 
 void
-WebGLContext::BindAttribLocation(WebGLProgram *prog, WebGLuint location,
+WebGLContext::BindAttribLocation(WebGLProgram *prog, GLuint location,
                                  const nsAString& name)
 {
-    if (!IsContextStable())
+    if (IsContextLost())
         return;
 
     if (!ValidateObject("bindAttribLocation: program", prog))
         return;
 
-    WebGLuint progname = prog->GLName();
+    GLuint progname = prog->GLName();
 
     if (!ValidateGLSLVariableName(name, "bindAttribLocation"))
         return;
 
     if (!ValidateAttribIndex(location, "bindAttribLocation"))
         return;
 
     NS_LossyConvertUTF16toASCII cname(name);
     nsCString mappedName;
     prog->MapIdentifier(cname, &mappedName);
     
     MakeContextCurrent();
     gl->fBindAttribLocation(progname, location, mappedName.get());
 }
 
 void
-WebGLContext::BindFramebuffer(WebGLenum target, WebGLFramebuffer *wfb)
+WebGLContext::BindFramebuffer(GLenum target, WebGLFramebuffer *wfb)
 {
-    if (!IsContextStable())
+    if (IsContextLost())
         return;
 
     if (target != LOCAL_GL_FRAMEBUFFER)
         return ErrorInvalidEnum("bindFramebuffer: target must be GL_FRAMEBUFFER");
 
     if (!ValidateObjectAllowDeletedOrNull("bindFramebuffer", wfb))
         return;
 
@@ -144,28 +145,28 @@ WebGLContext::BindFramebuffer(WebGLenum 
     if (wfb && wfb->IsDeleted())
         return;
 
     MakeContextCurrent();
 
     if (!wfb) {
         gl->fBindFramebuffer(target, 0);
     } else {
-        WebGLuint framebuffername = wfb->GLName();
+        GLuint framebuffername = wfb->GLName();
         gl->fBindFramebuffer(target, framebuffername);
         wfb->SetHasEverBeenBound(true);
     }
 
     mBoundFramebuffer = wfb;
 }
 
 void
-WebGLContext::BindRenderbuffer(WebGLenum target, WebGLRenderbuffer *wrb)
+WebGLContext::BindRenderbuffer(GLenum target, WebGLRenderbuffer *wrb)
 {
-    if (!IsContextStable())
+    if (IsContextLost())
         return;
 
     if (target != LOCAL_GL_RENDERBUFFER)
         return ErrorInvalidEnumInfo("bindRenderbuffer: target", target);
 
     if (!ValidateObjectAllowDeletedOrNull("bindRenderbuffer", wrb))
         return;
 
@@ -173,26 +174,26 @@ WebGLContext::BindRenderbuffer(WebGLenum
     if (wrb && wrb->IsDeleted())
         return;
 
     if (wrb)
         wrb->SetHasEverBeenBound(true);
 
     MakeContextCurrent();
 
-    WebGLuint renderbuffername = wrb ? wrb->GLName() : 0;
+    GLuint renderbuffername = wrb ? wrb->GLName() : 0;
     gl->fBindRenderbuffer(target, renderbuffername);
 
     mBoundRenderbuffer = wrb;
 }
 
 void
-WebGLContext::BindTexture(WebGLenum target, WebGLTexture *tex)
+WebGLContext::BindTexture(GLenum target, WebGLTexture *tex)
 {
-    if (!IsContextStable())
+    if (IsContextLost())
         return;
 
     if (!ValidateObjectAllowDeletedOrNull("bindTexture", tex))
         return;
 
     // silently ignore a deleted texture
     if (tex && tex->IsDeleted())
         return;
@@ -209,62 +210,62 @@ WebGLContext::BindTexture(WebGLenum targ
     MakeContextCurrent();
 
     if (tex)
         tex->Bind(target);
     else
         gl->fBindTexture(target, 0 /* == texturename */);
 }
 
-void WebGLContext::BlendEquation(WebGLenum mode)
+void WebGLContext::BlendEquation(GLenum mode)
 {
-    if (!IsContextStable())
+    if (IsContextLost())
         return;
 
     if (!ValidateBlendEquationEnum(mode, "blendEquation: mode"))
         return;
 
     MakeContextCurrent();
     gl->fBlendEquation(mode);
 }
 
-void WebGLContext::BlendEquationSeparate(WebGLenum modeRGB, WebGLenum modeAlpha)
+void WebGLContext::BlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha)
 {
-    if (!IsContextStable())
+    if (IsContextLost())
         return;
 
     if (!ValidateBlendEquationEnum(modeRGB, "blendEquationSeparate: modeRGB") ||
         !ValidateBlendEquationEnum(modeAlpha, "blendEquationSeparate: modeAlpha"))
         return;
 
     MakeContextCurrent();
     gl->fBlendEquationSeparate(modeRGB, modeAlpha);
 }
 
-void WebGLContext::BlendFunc(WebGLenum sfactor, WebGLenum dfactor)
+void WebGLContext::BlendFunc(GLenum sfactor, GLenum dfactor)
 {
-    if (!IsContextStable())
+    if (IsContextLost())
         return;
 
     if (!ValidateBlendFuncSrcEnum(sfactor, "blendFunc: sfactor") ||
         !ValidateBlendFuncDstEnum(dfactor, "blendFunc: dfactor"))
         return;
 
     if (!ValidateBlendFuncEnumsCompatibility(sfactor, dfactor, "blendFuncSeparate: srcRGB and dstRGB"))
         return;
 
     MakeContextCurrent();
     gl->fBlendFunc(sfactor, dfactor);
 }
 
 void
-WebGLContext::BlendFuncSeparate(WebGLenum srcRGB, WebGLenum dstRGB,
-                                WebGLenum srcAlpha, WebGLenum dstAlpha)
+WebGLContext::BlendFuncSeparate(GLenum srcRGB, GLenum dstRGB,
+                                GLenum srcAlpha, GLenum dstAlpha)
 {
-    if (!IsContextStable())
+    if (IsContextLost())
         return;
 
     if (!ValidateBlendFuncSrcEnum(srcRGB, "blendFuncSeparate: srcRGB") ||
         !ValidateBlendFuncSrcEnum(srcAlpha, "blendFuncSeparate: srcAlpha") ||
         !ValidateBlendFuncDstEnum(dstRGB, "blendFuncSeparate: dstRGB") ||
         !ValidateBlendFuncDstEnum(dstAlpha, "blendFuncSeparate: dstAlpha"))
         return;
 
@@ -272,55 +273,20 @@ WebGLContext::BlendFuncSeparate(WebGLenu
     // "Section 6.8 forgetting to mention alpha factors?" thread on the public_webgl mailing list
     if (!ValidateBlendFuncEnumsCompatibility(srcRGB, dstRGB, "blendFuncSeparate: srcRGB and dstRGB"))
         return;
 
     MakeContextCurrent();
     gl->fBlendFuncSeparate(srcRGB, dstRGB, srcAlpha, dstAlpha);
 }
 
-GLenum WebGLContext::CheckedBufferData(GLenum target,
-                                       GLsizeiptr size,
-                                       const GLvoid *data,
-                                       GLenum usage)
+GLenum
+WebGLContext::CheckFramebufferStatus(GLenum target)
 {
-#ifdef XP_MACOSX
-    // bug 790879
-    if (gl->WorkAroundDriverBugs() &&
-        int64_t(size) > INT32_MAX) // the cast avoids a potential always-true warning on 32bit
-    {
-        GenerateWarning("Rejecting valid bufferData call with size %lu to avoid a Mac bug", size);
-        return LOCAL_GL_INVALID_VALUE;
-    }
-#endif
-    WebGLBuffer *boundBuffer = nullptr;
-    if (target == LOCAL_GL_ARRAY_BUFFER) {
-        boundBuffer = mBoundArrayBuffer;
-    } else if (target == LOCAL_GL_ELEMENT_ARRAY_BUFFER) {
-        boundBuffer = mBoundVertexArray->mBoundElementArrayBuffer;
-    }
-    NS_ABORT_IF_FALSE(boundBuffer != nullptr, "no buffer bound for this target");
-    
-    bool sizeChanges = uint32_t(size) != boundBuffer->ByteLength();
-    if (sizeChanges) {
-        UpdateWebGLErrorAndClearGLError();
-        gl->fBufferData(target, size, data, usage);
-        GLenum error = LOCAL_GL_NO_ERROR;
-        UpdateWebGLErrorAndClearGLError(&error);
-        return error;
-    } else {
-        gl->fBufferData(target, size, data, usage);
-        return LOCAL_GL_NO_ERROR;
-    }
-}
-
-WebGLenum
-WebGLContext::CheckFramebufferStatus(WebGLenum target)
-{
-    if (!IsContextStable())
+    if (IsContextLost())
     {
         return LOCAL_GL_FRAMEBUFFER_UNSUPPORTED;
     }
 
     MakeContextCurrent();
     if (target != LOCAL_GL_FRAMEBUFFER) {
         ErrorInvalidEnum("checkFramebufferStatus: target must be FRAMEBUFFER");
         return 0;
@@ -358,30 +324,30 @@ WebGLContext::CheckFramebufferStatus(Web
     if(mBoundFramebuffer->HasIncompleteAttachment())
         return LOCAL_GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
     if(mBoundFramebuffer->HasAttachmentsOfMismatchedDimensions())
         return LOCAL_GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS;
     return gl->fCheckFramebufferStatus(target);
 }
 
 void
-WebGLContext::CopyTexSubImage2D_base(WebGLenum target,
-                                     WebGLint level,
-                                     WebGLenum internalformat,
-                                     WebGLint xoffset,
-                                     WebGLint yoffset,
-                                     WebGLint x,
-                                     WebGLint y,
-                                     WebGLsizei width,
-                                     WebGLsizei height,
+WebGLContext::CopyTexSubImage2D_base(GLenum target,
+                                     GLint level,
+                                     GLenum internalformat,
+                                     GLint xoffset,
+                                     GLint yoffset,
+                                     GLint x,
+                                     GLint y,
+                                     GLsizei width,
+                                     GLsizei height,
                                      bool sub)
 {
     const WebGLRectangleObject *framebufferRect = FramebufferRectangleObject();
-    WebGLsizei framebufferWidth = framebufferRect ? framebufferRect->Width() : 0;
-    WebGLsizei framebufferHeight = framebufferRect ? framebufferRect->Height() : 0;
+    GLsizei framebufferWidth = framebufferRect ? framebufferRect->Width() : 0;
+    GLsizei framebufferHeight = framebufferRect ? framebufferRect->Height() : 0;
 
     const char *info = sub ? "copyTexSubImage2D" : "copyTexImage2D";
 
     if (!ValidateLevelWidthHeightForTarget(target, level, width, height, info)) {
         return;
     }
 
     MakeContextCurrent();
@@ -458,26 +424,26 @@ WebGLContext::CopyTexSubImage2D_base(Web
         gl->fCopyTexSubImage2D(target, level, actual_xoffset, actual_yoffset, actual_x, actual_y, actual_width, actual_height);
     }
 
     if (!sub)
         ReattachTextureToAnyFramebufferToWorkAroundBugs(tex, level);
 }
 
 void
-WebGLContext::CopyTexImage2D(WebGLenum target,
-                             WebGLint level,
-                             WebGLenum internalformat,
-                             WebGLint x,
-                             WebGLint y,
-                             WebGLsizei width,
-                             WebGLsizei height,
-                             WebGLint border)
+WebGLContext::CopyTexImage2D(GLenum target,
+                             GLint level,
+                             GLenum internalformat,
+                             GLint x,
+                             GLint y,
+                             GLsizei width,
+                             GLsizei height,
+                             GLint border)
 {
-    if (!IsContextStable())
+    if (IsContextLost())
         return;
 
     switch (target) {
         case LOCAL_GL_TEXTURE_2D:
         case LOCAL_GL_TEXTURE_CUBE_MAP_POSITIVE_X:
         case LOCAL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
         case LOCAL_GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
         case LOCAL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
@@ -504,17 +470,17 @@ WebGLContext::CopyTexImage2D(WebGLenum t
         return ErrorInvalidValue("copyTexImage2D: border must be 0");
 
     if (width < 0 || height < 0)
         return ErrorInvalidValue("copyTexImage2D: width and height may not be negative");
 
     if (level < 0)
         return ErrorInvalidValue("copyTexImage2D: level may not be negative");
 
-    WebGLsizei maxTextureSize = MaxTextureSizeForTarget(target);
+    GLsizei maxTextureSize = MaxTextureSizeForTarget(target);
     if (!(maxTextureSize >> level))
         return ErrorInvalidValue("copyTexImage2D: 2^level exceeds maximum texture size");
 
     if (level >= 1) {
         if (!(is_pot_assuming_nonnegative(width) &&
               is_pot_assuming_nonnegative(height)))
             return ErrorInvalidValue("copyTexImage2D: with level > 0, width and height must be powers of two");
     }
@@ -567,26 +533,26 @@ WebGLContext::CopyTexImage2D(WebGLenum t
     } else {
         CopyTexSubImage2D_base(target, level, internalformat, 0, 0, x, y, width, height, false);
     }
     
     tex->SetImageInfo(target, level, width, height, internalformat, type);
 }
 
 void
-WebGLContext::CopyTexSubImage2D(WebGLenum target,
-                                WebGLint level,
-                                WebGLint xoffset,
-                                WebGLint yoffset,
-                                WebGLint x,
-                                WebGLint y,
-                                WebGLsizei width,
-                                WebGLsizei height)
+WebGLContext::CopyTexSubImage2D(GLenum target,
+                                GLint level,
+                                GLint xoffset,
+                                GLint yoffset,
+                                GLint x,
+                                GLint y,
+                                GLsizei width,
+                                GLsizei height)
 {
-    if (!IsContextStable())
+    if (IsContextLost())
         return;
 
     switch (target) {
         case LOCAL_GL_TEXTURE_2D:
         case LOCAL_GL_TEXTURE_CUBE_MAP_POSITIVE_X:
         case LOCAL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
         case LOCAL_GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
         case LOCAL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
@@ -595,45 +561,45 @@ WebGLContext::CopyTexSubImage2D(WebGLenu
             break;
         default:
             return ErrorInvalidEnumInfo("copyTexSubImage2D: target", target);
     }
 
     if (level < 0)
         return ErrorInvalidValue("copyTexSubImage2D: level may not be negative");
 
-    WebGLsizei maxTextureSize = MaxTextureSizeForTarget(target);
+    GLsizei maxTextureSize = MaxTextureSizeForTarget(target);
     if (!(maxTextureSize >> level))
         return ErrorInvalidValue("copyTexSubImage2D: 2^level exceeds maximum texture size");
 
     if (width < 0 || height < 0)
         return ErrorInvalidValue("copyTexSubImage2D: width and height may not be negative");
 
     if (xoffset < 0 || yoffset < 0)
         return ErrorInvalidValue("copyTexSubImage2D: xoffset and yoffset may not be negative");
 
     WebGLTexture *tex = activeBoundTextureForTarget(target);
     if (!tex)
         return ErrorInvalidOperation("copyTexSubImage2D: no texture bound to this target");
 
-    WebGLint face = WebGLTexture::FaceForTarget(target);
+    GLint face = WebGLTexture::FaceForTarget(target);
     if (!tex->HasImageInfoAt(level, face))
         return ErrorInvalidOperation("copyTexSubImage2D: no texture image previously defined for this level and face");
 
     const WebGLTexture::ImageInfo &imageInfo = tex->ImageInfoAt(level, face);
-    WebGLsizei texWidth = imageInfo.Width();
-    WebGLsizei texHeight = imageInfo.Height();
+    GLsizei texWidth = imageInfo.Width();
+    GLsizei texHeight = imageInfo.Height();
 
     if (xoffset + width > texWidth || xoffset + width < 0)
       return ErrorInvalidValue("copyTexSubImage2D: xoffset+width is too large");
 
     if (yoffset + height > texHeight || yoffset + height < 0)
       return ErrorInvalidValue("copyTexSubImage2D: yoffset+height is too large");
 
-    WebGLenum format = imageInfo.Format();
+    GLenum format = imageInfo.Format();
     bool texFormatRequiresAlpha = format == LOCAL_GL_RGBA ||
                                   format == LOCAL_GL_ALPHA ||
                                   format == LOCAL_GL_LUMINANCE_ALPHA;
     bool fboFormatHasAlpha = mBoundFramebuffer ? mBoundFramebuffer->ColorAttachment(0).HasAlpha()
                                                : bool(gl->GetPixelFormat().alpha > 0);
 
     if (texFormatRequiresAlpha && !fboFormatHasAlpha)
         return ErrorInvalidOperation("copyTexSubImage2D: texture format requires an alpha channel "
@@ -649,56 +615,56 @@ WebGLContext::CopyTexSubImage2D(WebGLenu
 
     return CopyTexSubImage2D_base(target, level, format, xoffset, yoffset, x, y, width, height, true);
 }
 
 
 already_AddRefed<WebGLProgram>
 WebGLContext::CreateProgram()
 {
-    if (!IsContextStable())
+    if (IsContextLost())
         return nullptr;
     nsRefPtr<WebGLProgram> globj = new WebGLProgram(this);
     return globj.forget();
 }
 
 already_AddRefed<WebGLShader>
-WebGLContext::CreateShader(WebGLenum type)
+WebGLContext::CreateShader(GLenum type)
 {
-    if (!IsContextStable())
+    if (IsContextLost())
         return nullptr;
 
     if (type != LOCAL_GL_VERTEX_SHADER &&
         type != LOCAL_GL_FRAGMENT_SHADER)
     {
         ErrorInvalidEnumInfo("createShader: type", type);
         return nullptr;
     }
 
     nsRefPtr<WebGLShader> shader = new WebGLShader(this, type);
     return shader.forget();
 }
 
 void
-WebGLContext::CullFace(WebGLenum face)
+WebGLContext::CullFace(GLenum face)
 {
-    if (!IsContextStable())
+    if (IsContextLost())
         return;
 
     if (!ValidateFaceEnum(face, "cullFace"))
         return;
 
     MakeContextCurrent();
     gl->fCullFace(face);
 }
 
 void
 WebGLContext::DeleteFramebuffer(WebGLFramebuffer* fbuf)
 {
-    if (!IsContextStable())
+    if (IsContextLost())
         return;
 
     if (!ValidateObjectAllowDeletedOrNull("deleteFramebuffer", fbuf))
         return;
 
     if (!fbuf || fbuf->IsDeleted())
         return;
 
@@ -707,17 +673,17 @@ WebGLContext::DeleteFramebuffer(WebGLFra
     if (mBoundFramebuffer == fbuf)
         BindFramebuffer(LOCAL_GL_FRAMEBUFFER,
                         static_cast<WebGLFramebuffer*>(nullptr));
 }
 
 void
 WebGLContext::DeleteRenderbuffer(WebGLRenderbuffer *rbuf)
 {
-    if (!IsContextStable())
+    if (IsContextLost())
         return;
 
     if (!ValidateObjectAllowDeletedOrNull("deleteRenderbuffer", rbuf))
         return;
 
     if (!rbuf || rbuf->IsDeleted())
         return;
 
@@ -729,105 +695,105 @@ WebGLContext::DeleteRenderbuffer(WebGLRe
                          static_cast<WebGLRenderbuffer*>(nullptr));
 
     rbuf->RequestDelete();
 }
 
 void
 WebGLContext::DeleteTexture(WebGLTexture *tex)
 {
-    if (!IsContextStable())
+    if (IsContextLost())
         return;
 
     if (!ValidateObjectAllowDeletedOrNull("deleteTexture", tex))
         return;
 
     if (!tex || tex->IsDeleted())
         return;
 
     if (mBoundFramebuffer)
         mBoundFramebuffer->DetachTexture(tex);
 
-    WebGLuint activeTexture = mActiveTexture;
+    GLuint activeTexture = mActiveTexture;
     for (int32_t i = 0; i < mGLMaxTextureUnits; i++) {
         if ((tex->Target() == LOCAL_GL_TEXTURE_2D && mBound2DTextures[i] == tex) ||
             (tex->Target() == LOCAL_GL_TEXTURE_CUBE_MAP && mBoundCubeMapTextures[i] == tex))
         {
             ActiveTexture(LOCAL_GL_TEXTURE0 + i);
             BindTexture(tex->Target(), static_cast<WebGLTexture*>(nullptr));
         }
     }
     ActiveTexture(LOCAL_GL_TEXTURE0 + activeTexture);
 
     tex->RequestDelete();
 }
 
 void
 WebGLContext::DeleteProgram(WebGLProgram *prog)
 {
-    if (!IsContextStable())
+    if (IsContextLost())
         return;
 
     if (!ValidateObjectAllowDeletedOrNull("deleteProgram", prog))
         return;
 
     if (!prog || prog->IsDeleted())
         return;
 
     prog->RequestDelete();
 }
 
 void
 WebGLContext::DeleteShader(WebGLShader *shader)
 {
-    if (!IsContextStable())
+    if (IsContextLost())
         return;
 
     if (!ValidateObjectAllowDeletedOrNull("deleteShader", shader))
         return;
 
     if (!shader || shader->IsDeleted())
         return;
 
     shader->RequestDelete();
 }
 
 void
 WebGLContext::DetachShader(WebGLProgram *program, WebGLShader *shader)
 {
-    if (!IsContextStable())
+    if (IsContextLost())
         return;
 
     if (!ValidateObject("detachShader: program", program) ||
         // it's valid to attempt to detach a deleted shader, since it's
         // still a shader
         !ValidateObjectAllowDeleted("detashShader: shader", shader))
         return;
 
     if (!program->DetachShader(shader))
         return ErrorInvalidOperation("detachShader: shader is not attached");
 }
 
 void
-WebGLContext::DepthFunc(WebGLenum func)
+WebGLContext::DepthFunc(GLenum func)
 {
-    if (!IsContextStable())
+    if (IsContextLost())
         return;
 
     if (!ValidateComparisonEnum(func, "depthFunc"))
         return;
 
     MakeContextCurrent();
     gl->fDepthFunc(func);
 }
 
 void
-WebGLContext::DepthRange(WebGLfloat zNear, WebGLfloat zFar)
+WebGLContext::DepthRange(GLfloat zNear, GLfloat zFar)
 {
-    if (!IsContextStable())
+    if (IsContextLost())
         return;
 
     if (zNear > zFar)
         return ErrorInvalidOperation("depthRange: the near value is greater than the far value!");
 
     MakeContextCurrent();
     gl->fDepthRange(zNear, zFar);
 }
@@ -848,41 +814,41 @@ WebGLContext::WhatDoesVertexAttrib0Need(
 #endif
 
     return (gl->IsGLES2() || mBoundVertexArray->mAttribBuffers[0].enabled) ? VertexAttrib0Status::Default
          : mCurrentProgram->IsAttribInUse(0)            ? VertexAttrib0Status::EmulatedInitializedArray
                                                         : VertexAttrib0Status::EmulatedUninitializedArray;
 }
 
 bool
-WebGLContext::DoFakeVertexAttrib0(WebGLuint vertexCount)
+WebGLContext::DoFakeVertexAttrib0(GLuint vertexCount)
 {
     int whatDoesAttrib0Need = WhatDoesVertexAttrib0Need();
 
     if (whatDoesAttrib0Need == VertexAttrib0Status::Default)
         return true;
 
     if (!mAlreadyWarnedAboutFakeVertexAttrib0) {
         GenerateWarning("Drawing without vertex attrib 0 array enabled forces the browser "
                         "to do expensive emulation work when running on desktop OpenGL "
                         "platforms, for example on Mac. It is preferable to always draw "
                         "with vertex attrib 0 array enabled, by using bindAttribLocation "
                         "to bind some always-used attribute to location 0.");
         mAlreadyWarnedAboutFakeVertexAttrib0 = true;
     }
 
-    CheckedUint32 checked_dataSize = CheckedUint32(vertexCount) * 4 * sizeof(WebGLfloat);
+    CheckedUint32 checked_dataSize = CheckedUint32(vertexCount) * 4 * sizeof(GLfloat);
 
     if (!checked_dataSize.isValid()) {
         ErrorOutOfMemory("Integer overflow trying to construct a fake vertex attrib 0 array for a draw-operation "
                          "with %d vertices. Try reducing the number of vertices.", vertexCount);
         return false;
     }
     
-    WebGLuint dataSize = checked_dataSize.value();
+    GLuint dataSize = checked_dataSize.value();
 
     if (!mFakeVertexAttrib0BufferObject) {
         gl->fGenBuffers(1, &mFakeVertexAttrib0BufferObject);
     }
 
     // if the VBO status is already exactly what we need, or if the only difference is that it's initialized and
     // we don't need it to be, then consider it OK
     bool vertexAttrib0BufferStatusOK =
@@ -905,17 +871,17 @@ WebGLContext::DoFakeVertexAttrib0(WebGLu
         mFakeVertexAttrib0BufferObjectVector[3] = mVertexAttrib0Vector[3];
 
         gl->fBindBuffer(LOCAL_GL_ARRAY_BUFFER, mFakeVertexAttrib0BufferObject);
 
         GLenum error = LOCAL_GL_NO_ERROR;
         UpdateWebGLErrorAndClearGLError();
 
         if (mFakeVertexAttrib0BufferStatus == VertexAttrib0Status::EmulatedInitializedArray) {
-            nsAutoArrayPtr<WebGLfloat> array(new WebGLfloat[4 * vertexCount]);
+            nsAutoArrayPtr<GLfloat> array(new GLfloat[4 * vertexCount]);
             for(size_t i = 0; i < vertexCount; ++i) {
                 array[4 * i + 0] = mVertexAttrib0Vector[0];
                 array[4 * i + 1] = mVertexAttrib0Vector[1];
                 array[4 * i + 2] = mVertexAttrib0Vector[2];
                 array[4 * i + 3] = mVertexAttrib0Vector[3];
             }
             gl->fBufferData(LOCAL_GL_ARRAY_BUFFER, dataSize, array, LOCAL_GL_DYNAMIC_DRAW);
         } else {
@@ -1000,17 +966,17 @@ WebGLContext::BindFakeBlackTextures()
 
         gl->fGenTextures(1, &mBlackTexture2D);
         gl->fBindTexture(LOCAL_GL_TEXTURE_2D, mBlackTexture2D);
         gl->fTexImage2D(LOCAL_GL_TEXTURE_2D, 0, LOCAL_GL_RGBA, 1, 1,
                         0, LOCAL_GL_RGBA, LOCAL_GL_UNSIGNED_BYTE, &black);
 
         gl->fGenTextures(1, &mBlackTextureCubeMap);
         gl->fBindTexture(LOCAL_GL_TEXTURE_CUBE_MAP, mBlackTextureCubeMap);
-        for (WebGLuint i = 0; i < 6; ++i) {
+        for (GLuint i = 0; i < 6; ++i) {
             gl->fTexImage2D(LOCAL_GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, LOCAL_GL_RGBA, 1, 1,
                             0, LOCAL_GL_RGBA, LOCAL_GL_UNSIGNED_BYTE, &black);
         }
 
         // Reset bound textures
         gl->fBindTexture(LOCAL_GL_TEXTURE_2D, bound2DTex);
         gl->fBindTexture(LOCAL_GL_TEXTURE_CUBE_MAP, boundCubeTex);
 
@@ -1046,47 +1012,47 @@ WebGLContext::UnbindFakeBlackTextures()
             gl->fBindTexture(LOCAL_GL_TEXTURE_CUBE_MAP, mBoundCubeMapTextures[i]->GLName());
         }
     }
 
     gl->fActiveTexture(LOCAL_GL_TEXTURE0 + mActiveTexture);
 }
 
 void
-WebGLContext::FramebufferRenderbuffer(WebGLenum target, WebGLenum attachment, WebGLenum rbtarget, WebGLRenderbuffer *wrb)
+WebGLContext::FramebufferRenderbuffer(GLenum target, GLenum attachment, GLenum rbtarget, WebGLRenderbuffer *wrb)
 {
-    if (!IsContextStable())
+    if (IsContextLost())
         return;
 
     if (!mBoundFramebuffer)
         return ErrorInvalidOperation("framebufferRenderbuffer: cannot modify framebuffer 0");
 
     return mBoundFramebuffer->FramebufferRenderbuffer(target, attachment, rbtarget, wrb);
 }
 
 void
-WebGLContext::FramebufferTexture2D(WebGLenum target,
-                                   WebGLenum attachment,
-                                   WebGLenum textarget,
+WebGLContext::FramebufferTexture2D(GLenum target,
+                                   GLenum attachment,
+                                   GLenum textarget,
                                    WebGLTexture *tobj,
-                                   WebGLint level)
+                                   GLint level)
 {
-    if (!IsContextStable())
+    if (IsContextLost())
         return;
 
     if (!mBoundFramebuffer)
         return ErrorInvalidOperation("framebufferRenderbuffer: cannot modify framebuffer 0");
 
     return mBoundFramebuffer->FramebufferTexture2D(target, attachment, textarget, tobj, level);
 }
 
 void
-WebGLContext::FrontFace(WebGLenum mode)
+WebGLContext::FrontFace(GLenum mode)
 {
-    if (!IsContextStable())
+    if (IsContextLost())
         return;
 
     switch (mode) {
         case LOCAL_GL_CW:
         case LOCAL_GL_CCW:
             break;
         default:
             return ErrorInvalidEnumInfo("frontFace: mode", mode);
@@ -1094,26 +1060,26 @@ WebGLContext::FrontFace(WebGLenum mode)
 
     MakeContextCurrent();
     gl->fFrontFace(mode);
 }
 
 already_AddRefed<WebGLActiveInfo>
 WebGLContext::GetActiveAttrib(WebGLProgram *prog, uint32_t index)
 {
-    if (!IsContextStable())
+    if (IsContextLost())
         return nullptr;
 
     if (!ValidateObject("getActiveAttrib: program", prog))
         return nullptr;
 
     MakeContextCurrent();
 
     GLint len = 0;
-    WebGLuint progname = prog->GLName();;
+    GLuint progname = prog->GLName();;
     gl->fGetProgramiv(progname, LOCAL_GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, &len);
     if (len == 0)
         return nullptr;
 
     nsAutoArrayPtr<char> name(new char[len]);
     GLint attrsize = 0;
     GLuint attrtype = 0;
 
@@ -1126,19 +1092,19 @@ WebGLContext::GetActiveAttrib(WebGLProgr
     prog->ReverseMapIdentifier(nsDependentCString(name), &reverseMappedName);
 
     nsRefPtr<WebGLActiveInfo> retActiveInfo =
         new WebGLActiveInfo(attrsize, attrtype, reverseMappedName);
     return retActiveInfo.forget();
 }
 
 void
-WebGLContext::GenerateMipmap(WebGLenum target)
+WebGLContext::GenerateMipmap(GLenum target)
 {
-    if (!IsContextStable())
+    if (IsContextLost())
         return;
 
     if (!ValidateTextureTargetEnum(target, "generateMipmap"))
         return;
 
     WebGLTexture *tex = activeBoundTextureForTarget(target);
 
     if (!tex)
@@ -1179,26 +1145,26 @@ WebGLContext::GenerateMipmap(WebGLenum t
     } else {
         gl->fGenerateMipmap(target);
     }
 }
 
 already_AddRefed<WebGLActiveInfo>
 WebGLContext::GetActiveUniform(WebGLProgram *prog, uint32_t index)
 {
-    if (!IsContextStable())
+    if (IsContextLost())
         return nullptr;
 
     if (!ValidateObject("getActiveUniform: program", prog))
         return nullptr;
 
     MakeContextCurrent();
 
     GLint len = 0;
-    WebGLuint progname = prog->GLName();
+    GLuint progname = prog->GLName();
     gl->fGetProgramiv(progname, LOCAL_GL_ACTIVE_UNIFORM_MAX_LENGTH, &len);
     if (len == 0)
         return nullptr;
 
     nsAutoArrayPtr<char> name(new char[len]);
 
     GLint usize = 0;
     GLuint utype = 0;
@@ -1232,17 +1198,17 @@ WebGLContext::GetActiveUniform(WebGLProg
     return retActiveInfo.forget();
 }
 
 void
 WebGLContext::GetAttachedShaders(WebGLProgram *prog,
                                  Nullable< nsTArray<WebGLShader*> > &retval)
 {
     retval.SetNull();
-    if (!IsContextStable())
+    if (IsContextLost())
         return;
 
     if (!ValidateObjectAllowNull("getAttachedShaders", prog))
         return;
 
     MakeContextCurrent();
 
     if (!prog) {
@@ -1250,42 +1216,42 @@ WebGLContext::GetAttachedShaders(WebGLPr
         ErrorInvalidValue("getAttachedShaders: invalid program");
     } else if (prog->AttachedShaders().Length() == 0) {
         retval.SetValue().TruncateLength(0);
     } else {
         retval.SetValue().AppendElements(prog->AttachedShaders());
     }
 }
 
-WebGLint
+GLint
 WebGLContext::GetAttribLocation(WebGLProgram *prog, const nsAString& name)
 {
-    if (!IsContextStable())
+    if (IsContextLost())
         return -1;
 
     if (!ValidateObject("getAttribLocation: program", prog))
         return -1;
 
     if (!ValidateGLSLVariableName(name, "getAttribLocation"))
         return -1; 
 
     NS_LossyConvertUTF16toASCII cname(name);
     nsCString mappedName;
     prog->MapIdentifier(cname, &mappedName);
 
-    WebGLuint progname = prog->GLName();
+    GLuint progname = prog->GLName();
 
     MakeContextCurrent();
     return gl->fGetAttribLocation(progname, mappedName.get());
 }
 
 JS::Value
-WebGLContext::GetBufferParameter(WebGLenum target, WebGLenum pname)
+WebGLContext::GetBufferParameter(GLenum target, GLenum pname)
 {
-    if (!IsContextStable())
+    if (IsContextLost())
         return JS::NullValue();
 
     if (target != LOCAL_GL_ARRAY_BUFFER && target != LOCAL_GL_ELEMENT_ARRAY_BUFFER) {
         ErrorInvalidEnumInfo("getBufferParameter: target", target);
         return JS::NullValue();
     }
 
     MakeContextCurrent();
@@ -1309,37 +1275,37 @@ WebGLContext::GetBufferParameter(WebGLen
             ErrorInvalidEnumInfo("getBufferParameter: parameter", pname);
     }
 
     return JS::NullValue();
 }
 
 JS::Value
 WebGLContext::GetFramebufferAttachmentParameter(JSContext* cx,
-                                                WebGLenum target,
-                                                WebGLenum attachment,
-                                                WebGLenum pname,
+                                                GLenum target,
+                                                GLenum attachment,
+                                                GLenum pname,
                                                 ErrorResult& rv)
 {
-    if (!IsContextStable())
+    if (IsContextLost())
         return JS::NullValue();
 
     if (target != LOCAL_GL_FRAMEBUFFER) {
         ErrorInvalidEnumInfo("getFramebufferAttachmentParameter: target", target);
         return JS::NullValue();
     }
 
     if (attachment != LOCAL_GL_DEPTH_ATTACHMENT &&
         attachment != LOCAL_GL_STENCIL_ATTACHMENT &&
         attachment != LOCAL_GL_DEPTH_STENCIL_ATTACHMENT)
     {
         if (IsExtensionEnabled(WEBGL_draw_buffers))
         {
             if (attachment < LOCAL_GL_COLOR_ATTACHMENT0 ||
-                attachment >= WebGLenum(LOCAL_GL_COLOR_ATTACHMENT0 + mGLMaxColorAttachments))
+                attachment >= GLenum(LOCAL_GL_COLOR_ATTACHMENT0 + mGLMaxColorAttachments))
             {
                 ErrorInvalidEnumInfo("getFramebufferAttachmentParameter: attachment", attachment);
                 return JS::NullValue();
             }
 
             mBoundFramebuffer->EnsureColorAttachments(attachment - LOCAL_GL_COLOR_ATTACHMENT0);
         }
         else if (attachment != LOCAL_GL_COLOR_ATTACHMENT0)
@@ -1402,19 +1368,19 @@ WebGLContext::GetFramebufferAttachmentPa
                 return JS::NullValue();
         }
     }
 
     return JS::NullValue();
 }
 
 JS::Value
-WebGLContext::GetRenderbufferParameter(WebGLenum target, WebGLenum pname)
+WebGLContext::GetRenderbufferParameter(GLenum target, GLenum pname)
 {
-    if (!IsContextStable())
+    if (IsContextLost())
         return JS::NullValue();
 
     if (target != LOCAL_GL_RENDERBUFFER) {
         ErrorInvalidEnumInfo("getRenderbufferParameter: target", target);
         return JS::NullValue();
     }
 
     if (!mBoundRenderbuffer) {
@@ -1447,48 +1413,48 @@ WebGLContext::GetRenderbufferParameter(W
     }
 
     return JS::NullValue();
 }
 
 already_AddRefed<WebGLTexture>
 WebGLContext::CreateTexture()
 {
-    if (!IsContextStable())
+    if (IsContextLost())
         return nullptr;
     nsRefPtr<WebGLTexture> globj = new WebGLTexture(this);
     return globj.forget();
 }
 
-WebGLenum
+GLenum
 WebGLContext::GetError()
 {
-    if (mContextStatus == ContextStable) {
+    if (mContextStatus == ContextNotLost) {
         MakeContextCurrent();
         UpdateWebGLErrorAndClearGLError();
     } else if (!mContextLostErrorSet) {
         mWebGLError = LOCAL_GL_CONTEXT_LOST;
         mContextLostErrorSet = true;
     }
 
-    WebGLenum err = mWebGLError;
+    GLenum err = mWebGLError;
     mWebGLError = LOCAL_GL_NO_ERROR;
     return err;
 }
 
 JS::Value
-WebGLContext::GetProgramParameter(WebGLProgram *prog, WebGLenum pname)
+WebGLContext::GetProgramParameter(WebGLProgram *prog, GLenum pname)
 {
-    if (!IsContextStable())
+    if (IsContextLost())
         return JS::NullValue();
 
     if (!ValidateObjectAllowDeleted("getProgramParameter: program", prog))
         return JS::NullValue();
 
-    WebGLuint progname = prog->GLName();
+    GLuint progname = prog->GLName();
 
     MakeContextCurrent();
 
     switch (pname) {
         case LOCAL_GL_ATTACHED_SHADERS:
         case LOCAL_GL_ACTIVE_UNIFORMS:
         case LOCAL_GL_ACTIVE_ATTRIBUTES:
         {
@@ -1534,28 +1500,28 @@ WebGLContext::GetProgramInfoLog(WebGLPro
         retval.SetIsVoid(true);
     else
         CopyASCIItoUTF16(s, retval);
 }
 
 void
 WebGLContext::GetProgramInfoLog(WebGLProgram *prog, nsACString& retval)
 {
-    if (!IsContextStable())
+    if (IsContextLost())
     {
         retval.SetIsVoid(true);
         return;
     }
 
     if (!ValidateObject("getProgramInfoLog: program", prog)) {
         retval.Truncate();
         return;
     }
         
-    WebGLuint progname = prog->GLName();
+    GLuint progname = prog->GLName();
 
     MakeContextCurrent();
 
     GLint k = -1;
     gl->fGetProgramiv(progname, LOCAL_GL_INFO_LOG_LENGTH, &k);
     if (k == -1) {
         // If GetProgramiv doesn't modify |k|,
         // it's because there was a GL error.
@@ -1572,27 +1538,27 @@ WebGLContext::GetProgramInfoLog(WebGLPro
     retval.SetCapacity(k);
     gl->fGetProgramInfoLog(progname, k, &k, (char*) retval.BeginWriting());
     retval.SetLength(k);
 }
 
 // here we have to support all pnames with both int and float params.
 // See this discussion:
 //  https://www.khronos.org/webgl/public-mailing-list/archives/1008/msg00014.html
-void WebGLContext::TexParameter_base(WebGLenum target, WebGLenum pname,
-                                     WebGLint *intParamPtr,
-                                     WebGLfloat *floatParamPtr)
+void WebGLContext::TexParameter_base(GLenum target, GLenum pname,
+                                     GLint *intParamPtr,
+                                     GLfloat *floatParamPtr)
 {
     MOZ_ASSERT(intParamPtr || floatParamPtr);
 
-    if (!IsContextStable())
+    if (IsContextLost())
         return;
 
-    WebGLint intParam = intParamPtr ? *intParamPtr : WebGLint(*floatParamPtr);
-    WebGLfloat floatParam = floatParamPtr ? *floatParamPtr : WebGLfloat(*intParamPtr);
+    GLint intParam = intParamPtr ? *intParamPtr : GLint(*floatParamPtr);
+    GLfloat floatParam = floatParamPtr ? *floatParamPtr : GLfloat(*intParamPtr);
 
     if (!ValidateTextureTargetEnum(target, "texParameter: target"))
         return;
 
     WebGLTexture *tex = activeBoundTextureForTarget(target);
     if (!tex)
         return ErrorInvalidOperation("texParameter: no texture is bound to this target");
 
@@ -1679,19 +1645,19 @@ void WebGLContext::TexParameter_base(Web
     MakeContextCurrent();
     if (intParamPtr)
         gl->fTexParameteri(target, pname, intParam);
     else
         gl->fTexParameterf(target, pname, floatParam);
 }
 
 JS::Value
-WebGLContext::GetTexParameter(WebGLenum target, WebGLenum pname)
+WebGLContext::GetTexParameter(GLenum target, GLenum pname)
 {
-    if (!IsContextStable())
+    if (IsContextLost())
         return JS::NullValue();
 
     MakeContextCurrent();
 
     if (!ValidateTextureTargetEnum(target, "getTexParameter: target"))
         return JS::NullValue();
 
     if (!activeBoundTextureForTarget(target)) {
@@ -1725,17 +1691,17 @@ WebGLContext::GetTexParameter(WebGLenum 
 
     return JS::NullValue();
 }
 
 JS::Value
 WebGLContext::GetUniform(JSContext* cx, WebGLProgram *prog,
                          WebGLUniformLocation *location, ErrorResult& rv)
 {
-    if (!IsContextStable())
+    if (IsContextLost())
         return JS::NullValue();
 
     if (!ValidateObject("getUniform: program", prog))
         return JS::NullValue();
 
     if (!ValidateObject("getUniform: location", location))
         return JS::NullValue();
 
@@ -1744,17 +1710,17 @@ WebGLContext::GetUniform(JSContext* cx, 
         return JS::NullValue();
     }
 
     if (location->ProgramGeneration() != prog->Generation()) {
         ErrorInvalidOperation("getUniform: this uniform location is obsolete since the program has been relinked");
         return JS::NullValue();
     }
 
-    WebGLuint progname = prog->GLName();
+    GLuint progname = prog->GLName();
 
     MakeContextCurrent();
 
     GLint uniforms = 0;
     GLint uniformNameMaxLength = 0;
     gl->fGetProgramiv(progname, LOCAL_GL_ACTIVE_UNIFORMS, &uniforms);
     gl->fGetProgramiv(progname, LOCAL_GL_ACTIVE_UNIFORM_MAX_LENGTH, &uniformNameMaxLength);
 
@@ -1857,48 +1823,48 @@ WebGLContext::GetUniform(JSContext* cx, 
 
     // Else preserving behavior, but I'm not sure this is correct per spec
     return JS::UndefinedValue();
 }
 
 already_AddRefed<WebGLUniformLocation>
 WebGLContext::GetUniformLocation(WebGLProgram *prog, const nsAString& name)
 {
-    if (!IsContextStable())
+    if (IsContextLost())
         return nullptr;
 
     if (!ValidateObject("getUniformLocation: program", prog))
         return nullptr;
 
     if (!ValidateGLSLVariableName(name, "getUniformLocation"))
         return nullptr;
 
     NS_LossyConvertUTF16toASCII cname(name);
     nsCString mappedName;
     prog->MapIdentifier(cname, &mappedName);
 
-    WebGLuint progname = prog->GLName();
+    GLuint progname = prog->GLName();
     MakeContextCurrent();
     GLint intlocation = gl->fGetUniformLocation(progname, mappedName.get());
 
     nsRefPtr<WebGLUniformLocation> loc;
     if (intlocation >= 0) {
         WebGLUniformInfo info = prog->GetUniformInfoForMappedIdentifier(mappedName);
         loc = new WebGLUniformLocation(this,
                                        prog,
                                        intlocation,
                                        info);
     }
     return loc.forget();
 }
 
 void
-WebGLContext::Hint(WebGLenum target, WebGLenum mode)
+WebGLContext::Hint(GLenum target, GLenum mode)
 {
-    if (!IsContextStable())
+    if (IsContextLost())
         return;
 
     bool isValid = false;
 
     switch (target) {
         case LOCAL_GL_GENERATE_MIPMAP_HINT:
             isValid = true;
             break;
@@ -1912,58 +1878,58 @@ WebGLContext::Hint(WebGLenum target, Web
         return ErrorInvalidEnum("hint: invalid hint");
 
     gl->fHint(target, mode);
 }
 
 bool
 WebGLContext::IsFramebuffer(WebGLFramebuffer *fb)
 {
-    if (!IsContextStable())
+    if (IsContextLost())
         return false;
 
     return ValidateObjectAllowDeleted("isFramebuffer", fb) &&
         !fb->IsDeleted() &&
         fb->HasEverBeenBound();
 }
 
 bool
 WebGLContext::IsProgram(WebGLProgram *prog)
 {
-    if (!IsContextStable())
+    if (IsContextLost())
         return false;
 
     return ValidateObjectAllowDeleted("isProgram", prog) && !prog->IsDeleted();
 }
 
 bool
 WebGLContext::IsRenderbuffer(WebGLRenderbuffer *rb)
 {
-    if (!IsContextStable())
+    if (IsContextLost())
         return false;
 
     return ValidateObjectAllowDeleted("isRenderBuffer", rb) &&
         !rb->IsDeleted() &&
         rb->HasEverBeenBound();
 }
 
 bool
 WebGLContext::IsShader(WebGLShader *shader)
 {
-    if (!IsContextStable())
+    if (IsContextLost())
         return false;
 
     return ValidateObjectAllowDeleted("isShader", shader) &&
         !shader->IsDeleted();
 }
 
 bool
 WebGLContext::IsTexture(WebGLTexture *tex)
 {
-    if (!IsContextStable())
+    if (IsContextLost())
         return false;
 
     return ValidateObjectAllowDeleted("isTexture", tex) &&
         !tex->IsDeleted() &&
         tex->HasEverBeenBound();
 }
 
 // Try to bind an attribute that is an array to location 0:
@@ -1994,17 +1960,17 @@ bool WebGLContext::BindArrayAttribToLoca
         return true;
     }
     return false;
 }
 
 void
 WebGLContext::LinkProgram(WebGLProgram *program)
 {
-    if (!IsContextStable())
+    if (IsContextLost())
         return;
 
     if (!ValidateObject("linkProgram", program))
         return;
 
     InvalidateBufferFetching(); // we do it early in this function
     // as some of the validation below changes program state
 
@@ -2122,19 +2088,19 @@ WebGLContext::LinkProgram(WebGLProgram *
                                     log.get());
                 }
             }
         }
     }
 }
 
 void
-WebGLContext::PixelStorei(WebGLenum pname, WebGLint param)
+WebGLContext::PixelStorei(GLenum pname, GLint param)
 {
-    if (!IsContextStable())
+    if (IsContextLost())
         return;
 
     switch (pname) {
         case UNPACK_FLIP_Y_WEBGL:
             mPixelStoreFlipY = (param != 0);
             break;
         case UNPACK_PREMULTIPLY_ALPHA_WEBGL:
             mPixelStorePremultiplyAlpha = (param != 0);
@@ -2160,39 +2126,39 @@ WebGLContext::PixelStorei(WebGLenum pnam
             gl->fPixelStorei(pname, param);
             break;
         default:
             return ErrorInvalidEnumInfo("pixelStorei: parameter", pname);
     }
 }
 
 void
-WebGLContext::ReadPixels(WebGLint x, WebGLint y, WebGLsizei width,
-                         WebGLsizei height, WebGLenum format,
-                         WebGLenum type, const Nullable<ArrayBufferView> &pixels,
+WebGLContext::ReadPixels(GLint x, GLint y, GLsizei width,
+                         GLsizei height, GLenum format,
+                         GLenum type, const Nullable<ArrayBufferView> &pixels,
                          ErrorResult& rv)
 {
-    if (!IsContextStable()) {
+    if (IsContextLost()) {
         return;
     }
 
     if (mCanvasElement->IsWriteOnly() && !nsContentUtils::IsCallerChrome()) {
         GenerateWarning("readPixels: Not allowed");
         return rv.Throw(NS_ERROR_DOM_SECURITY_ERR);
     }
 
     if (width < 0 || height < 0)
         return ErrorInvalidValue("readPixels: negative size passed");
 
     if (pixels.IsNull())
         return ErrorInvalidValue("readPixels: null destination buffer");
 
     const WebGLRectangleObject *framebufferRect = FramebufferRectangleObject();
-    WebGLsizei framebufferWidth = framebufferRect ? framebufferRect->Width() : 0;
-    WebGLsizei framebufferHeight = framebufferRect ? framebufferRect->Height() : 0;
+    GLsizei framebufferWidth = framebufferRect ? framebufferRect->Width() : 0;
+    GLsizei framebufferHeight = framebufferRect ? framebufferRect->Height() : 0;
 
     uint32_t channels = 0;
 
     // Check the format param
     switch (format) {
         case LOCAL_GL_ALPHA:
             channels = 1;
             break;
@@ -2386,35 +2352,35 @@ WebGLContext::ReadPixels(WebGLint x, Web
                 NS_WARNING("Unhandled case, how'd we get here?");
                 return rv.Throw(NS_ERROR_FAILURE);
             }
         }            
     }
 }
 
 void
-WebGLContext::RenderbufferStorage(WebGLenum target, WebGLenum internalformat, WebGLsizei width, WebGLsizei height)
+WebGLContext::RenderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height)
 {
-    if (!IsContextStable())
+    if (IsContextLost())
         return;
 
     if (!mBoundRenderbuffer || !mBoundRenderbuffer->GLName())
         return ErrorInvalidOperation("renderbufferStorage called on renderbuffer 0");
 
     if (target != LOCAL_GL_RENDERBUFFER)
         return ErrorInvalidEnumInfo("renderbufferStorage: target", target);
 
     if (width < 0 || height < 0)
         return ErrorInvalidValue("renderbufferStorage: width and height must be >= 0");
 
     if (width > mGLMaxRenderbufferSize || height > mGLMaxRenderbufferSize)
         return ErrorInvalidValue("renderbufferStorage: width or height exceeds maximum renderbuffer size");
 
     // certain OpenGL ES renderbuffer formats may not exist on desktop OpenGL
-    WebGLenum internalformatForGL = internalformat;
+    GLenum internalformatForGL = internalformat;
 
     switch (internalformat) {
     case LOCAL_GL_RGBA4:
     case LOCAL_GL_RGB5_A1:
         // 16-bit RGBA formats are not supported on desktop GL
         if (!gl->IsGLES2()) internalformatForGL = LOCAL_GL_RGBA8;
         break;
     case LOCAL_GL_RGB565:
@@ -2463,50 +2429,50 @@ WebGLContext::RenderbufferStorage(WebGLe
 
     mBoundRenderbuffer->SetInternalFormat(internalformat);
     mBoundRenderbuffer->SetInternalFormatForGL(internalformatForGL);
     mBoundRenderbuffer->setDimensions(width, height);
     mBoundRenderbuffer->SetInitialized(false);
 }
 
 void
-WebGLContext::Scissor(WebGLint x, WebGLint y, WebGLsizei width, WebGLsizei height)
+WebGLContext::Scissor(GLint x, GLint y, GLsizei width, GLsizei height)
 {
-    if (!IsContextStable())
+    if (IsContextLost())
         return;
 
     if (width < 0 || height < 0)
         return ErrorInvalidValue("scissor: negative size");
 
     MakeContextCurrent();
     gl->fScissor(x, y, width, height);
 }
 
 void
-WebGLContext::StencilFunc(WebGLenum func, WebGLint ref, WebGLuint mask)
+WebGLContext::StencilFunc(GLenum func, GLint ref, GLuint mask)
 {
-    if (!IsContextStable())
+    if (IsContextLost())
         return;
 
     if (!ValidateComparisonEnum(func, "stencilFunc: func"))
         return;
 
     mStencilRefFront = ref;
     mStencilRefBack = ref;
     mStencilValueMaskFront = mask;
     mStencilValueMaskBack = mask;
 
     MakeContextCurrent();
     gl->fStencilFunc(func, ref, mask);
 }
 
 void
-WebGLContext::StencilFuncSeparate(WebGLenum face, WebGLenum func, WebGLint ref, WebGLuint mask)
+WebGLContext::StencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)
 {
-    if (!IsContextStable())
+    if (IsContextLost())
         return;
 
     if (!ValidateFaceEnum(face, "stencilFuncSeparate: face") ||
         !ValidateComparisonEnum(func, "stencilFuncSeparate: func"))
         return;
 
     switch (face) {
         case LOCAL_GL_FRONT_AND_BACK:
@@ -2525,34 +2491,34 @@ WebGLContext::StencilFuncSeparate(WebGLe
             break;
     }
 
     MakeContextCurrent();
     gl->fStencilFuncSeparate(face, func, ref, mask);
 }
 
 void
-WebGLContext::StencilOp(WebGLenum sfail, WebGLenum dpfail, WebGLenum dppass)
+WebGLContext::StencilOp(GLenum sfail, GLenum dpfail, GLenum dppass)
 {
-    if (!IsContextStable())
+    if (IsContextLost())
         return;
 
     if (!ValidateStencilOpEnum(sfail, "stencilOp: sfail") ||
         !ValidateStencilOpEnum(dpfail, "stencilOp: dpfail") ||
         !ValidateStencilOpEnum(dppass, "stencilOp: dppass"))
         return;
 
     MakeContextCurrent();
     gl->fStencilOp(sfail, dpfail, dppass);
 }
 
 void
-WebGLContext::StencilOpSeparate(WebGLenum face, WebGLenum sfail, WebGLenum dpfail, WebGLenum dppass)
+WebGLContext::StencilOpSeparate(GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass)
 {
-    if (!IsContextStable())
+    if (IsContextLost())
         return;
 
     if (!ValidateFaceEnum(face, "stencilOpSeparate: face") ||
         !ValidateStencilOpEnum(sfail, "stencilOpSeparate: sfail") ||
         !ValidateStencilOpEnum(dpfail, "stencilOpSeparate: dpfail") ||
         !ValidateStencilOpEnum(dppass, "stencilOpSeparate: dppass"))
         return;
 
@@ -2630,50 +2596,50 @@ WebGLContext::SurfaceFromElementResultTo
     }
 
     return NS_OK;
 }
 
 
 
 void
-WebGLContext::Uniform1i(WebGLUniformLocation *location_object, WebGLint a1)
+WebGLContext::Uniform1i(WebGLUniformLocation *location_object, GLint a1)
 {
     GLint location;
     if (!ValidateUniformSetter("Uniform1i", location_object, location))
         return;
 
     if (!ValidateSamplerUniformSetter("Uniform1i", location_object, a1))
         return;
 
     MakeContextCurrent();
     gl->fUniform1i(location, a1);
 }
 
 void
-WebGLContext::Uniform2i(WebGLUniformLocation *location_object, WebGLint a1,
-                        WebGLint a2)
+WebGLContext::Uniform2i(WebGLUniformLocation *location_object, GLint a1,
+                        GLint a2)
 {
     GLint location;
     if (!ValidateUniformSetter("Uniform2i", location_object, location))
         return;
 
     if (!ValidateSamplerUniformSetter("Uniform2i", location_object, a1) ||
         !ValidateSamplerUniformSetter("Uniform2i", location_object, a2))
     {
         return;
     }
 
     MakeContextCurrent();
     gl->fUniform2i(location, a1, a2);
 }
 
 void
-WebGLContext::Uniform3i(WebGLUniformLocation *location_object, WebGLint a1,
-                        WebGLint a2, WebGLint a3)
+WebGLContext::Uniform3i(WebGLUniformLocation *location_object, GLint a1,
+                        GLint a2, GLint a3)
 {
     GLint location;
     if (!ValidateUniformSetter("Uniform3i", location_object, location))
         return;
 
     if (!ValidateSamplerUniformSetter("Uniform3i", location_object, a1) ||
         !ValidateSamplerUniformSetter("Uniform3i", location_object, a2) ||
         !ValidateSamplerUniformSetter("Uniform3i", location_object, a3))
@@ -2681,18 +2647,18 @@ WebGLContext::Uniform3i(WebGLUniformLoca
         return;
     }
 
     MakeContextCurrent();
     gl->fUniform3i(location, a1, a2, a3);
 }
 
 void
-WebGLContext::Uniform4i(WebGLUniformLocation *location_object, WebGLint a1,
-                        WebGLint a2, WebGLint a3, WebGLint a4)
+WebGLContext::Uniform4i(WebGLUniformLocation *location_object, GLint a1,
+                        GLint a2, GLint a3, GLint a4)
 {
     GLint location;
     if (!ValidateUniformSetter("Uniform4i", location_object, location))
         return;
 
     if (!ValidateSamplerUniformSetter("Uniform4i", location_object, a1) ||
         !ValidateSamplerUniformSetter("Uniform4i", location_object, a2) ||
         !ValidateSamplerUniformSetter("Uniform4i", location_object, a3) ||
@@ -2701,61 +2667,61 @@ WebGLContext::Uniform4i(WebGLUniformLoca
         return;
     }
 
     MakeContextCurrent();
     gl->fUniform4i(location, a1, a2, a3, a4);
 }
 
 void
-WebGLContext::Uniform1f(WebGLUniformLocation *location_object, WebGLfloat a1)
+WebGLContext::Uniform1f(WebGLUniformLocation *location_object, GLfloat a1)
 {
     GLint location;
     if (!ValidateUniformSetter("Uniform1f", location_object, location))
         return;
     MakeContextCurrent();
     gl->fUniform1f(location, a1);
 }
 
 void
-WebGLContext::Uniform2f(WebGLUniformLocation *location_object, WebGLfloat a1,
-                        WebGLfloat a2)
+WebGLContext::Uniform2f(WebGLUniformLocation *location_object, GLfloat a1,
+                        GLfloat a2)
 {
     GLint location;
     if (!ValidateUniformSetter("Uniform2f", location_object, location))
         return;
     MakeContextCurrent();
     gl->fUniform2f(location, a1, a2);
 }
 
 void
-WebGLContext::Uniform3f(WebGLUniformLocation *location_object, WebGLfloat a1,
-                        WebGLfloat a2, WebGLfloat a3)
+WebGLContext::Uniform3f(WebGLUniformLocation *location_object, GLfloat a1,
+                        GLfloat a2, GLfloat a3)
 {
     GLint location;
     if (!ValidateUniformSetter("Uniform3f", location_object, location))
         return;
     MakeContextCurrent();
     gl->fUniform3f(location, a1, a2, a3);
 }
 
 void
-WebGLContext::Uniform4f(WebGLUniformLocation *location_object, WebGLfloat a1,
-                        WebGLfloat a2, WebGLfloat a3, WebGLfloat a4)
+WebGLContext::Uniform4f(WebGLUniformLocation *location_object, GLfloat a1,
+                        GLfloat a2, GLfloat a3, GLfloat a4)
 {
     GLint location;
     if (!ValidateUniformSetter("Uniform4f", location_object, location))
         return;
     MakeContextCurrent();
     gl->fUniform4f(location, a1, a2, a3, a4);
 }
 
 void
 WebGLContext::Uniform1iv_base(WebGLUniformLocation *location_object,
-                              uint32_t arrayLength, const WebGLint* data)
+                              uint32_t arrayLength, const GLint* data)
 {
     uint32_t numElementsToUpload;
     GLint location;
     if (!ValidateUniformArraySetter("Uniform1iv", 1, location_object, location,
                                     numElementsToUpload, arrayLength)) {
         return;
     }
 
@@ -2763,17 +2729,17 @@ WebGLContext::Uniform1iv_base(WebGLUnifo
         return;
 
     MakeContextCurrent();
     gl->fUniform1iv(location, numElementsToUpload, data);
 }
 
 void
 WebGLContext::Uniform2iv_base(WebGLUniformLocation *location_object,
-                              uint32_t arrayLength, const WebGLint* data)
+                              uint32_t arrayLength, const GLint* data)
 {
     uint32_t numElementsToUpload;
     GLint location;
     if (!ValidateUniformArraySetter("Uniform2iv", 2, location_object, location,
                                     numElementsToUpload, arrayLength)) {
         return;
     }
 
@@ -2784,17 +2750,17 @@ WebGLContext::Uniform2iv_base(WebGLUnifo
     }
 
     MakeContextCurrent();
     gl->fUniform2iv(location, numElementsToUpload, data);
 }
 
 void
 WebGLContext::Uniform3iv_base(WebGLUniformLocation *location_object,
-                              uint32_t arrayLength, const WebGLint* data)
+                              uint32_t arrayLength, const GLint* data)
 {
     uint32_t numElementsToUpload;
     GLint location;
     if (!ValidateUniformArraySetter("Uniform3iv", 3, location_object, location,
                                     numElementsToUpload, arrayLength)) {
         return;
     }
 
@@ -2806,17 +2772,17 @@ WebGLContext::Uniform3iv_base(WebGLUnifo
     }
 
     MakeContextCurrent();
     gl->fUniform3iv(location, numElementsToUpload, data);
 }
 
 void
 WebGLContext::Uniform4iv_base(WebGLUniformLocation *location_object,
-                              uint32_t arrayLength, const WebGLint* data)
+                              uint32_t arrayLength, const GLint* data)
 {
     uint32_t numElementsToUpload;
     GLint location;
     if (!ValidateUniformArraySetter("Uniform4iv", 4, location_object, location,
                                     numElementsToUpload, arrayLength)) {
         return;
     }
 
@@ -2829,59 +2795,59 @@ WebGLContext::Uniform4iv_base(WebGLUnifo
     }
 
     MakeContextCurrent();
     gl->fUniform4iv(location, numElementsToUpload, data);
 }
 
 void
 WebGLContext::Uniform1fv_base(WebGLUniformLocation *location_object,
-                              uint32_t arrayLength, const WebGLfloat* data)
+                              uint32_t arrayLength, const GLfloat* data)
 {
     uint32_t numElementsToUpload;
     GLint location;
     if (!ValidateUniformArraySetter("Uniform1fv", 1, location_object, location,
                                     numElementsToUpload, arrayLength)) {
         return;
     }
     MakeContextCurrent();
     gl->fUniform1fv(location, numElementsToUpload, data);
 }
 
 void
 WebGLContext::Uniform2fv_base(WebGLUniformLocation *location_object,
-                              uint32_t arrayLength, const WebGLfloat* data)
+                              uint32_t arrayLength, const GLfloat* data)
 {
     uint32_t numElementsToUpload;
     GLint location;
     if (!ValidateUniformArraySetter("Uniform2fv", 2, location_object, location,
                                     numElementsToUpload, arrayLength)) {
         return;
     }
     MakeContextCurrent();
     gl->fUniform2fv(location, numElementsToUpload, data);
 }
 
 void
 WebGLContext::Uniform3fv_base(WebGLUniformLocation *location_object,
-                              uint32_t arrayLength, const WebGLfloat* data)
+                              uint32_t arrayLength, const GLfloat* data)
 {
     uint32_t numElementsToUpload;
     GLint location;
     if (!ValidateUniformArraySetter("Uniform3fv", 3, location_object, location,
                                     numElementsToUpload, arrayLength)) {
         return;
     }
     MakeContextCurrent();
     gl->fUniform3fv(location, numElementsToUpload, data);
 }
 
 void
 WebGLContext::Uniform4fv_base(WebGLUniformLocation *location_object,
-                              uint32_t arrayLength, const WebGLfloat* data)
+                              uint32_t arrayLength, const GLfloat* data)
 {
     uint32_t numElementsToUpload;
     GLint location;
     if (!ValidateUniformArraySetter("Uniform4fv", 4, location_object, location,
                                     numElementsToUpload, arrayLength)) {
         return;
     }
     MakeContextCurrent();
@@ -2931,100 +2897,100 @@ WebGLContext::UniformMatrix4fv_base(WebG
     }
     MakeContextCurrent();
     gl->fUniformMatrix4fv(location, numElementsToUpload, false, data);
 }
 
 void
 WebGLContext::UseProgram(WebGLProgram *prog)
 {
-    if (!IsContextStable())
+    if (IsContextLost())
         return;
 
     if (!ValidateObjectAllowNull("useProgram", prog))
         return;
 
     MakeContextCurrent();
 
     InvalidateBufferFetching();
 
-    WebGLuint progname = prog ? prog->GLName() : 0;
+    GLuint progname = prog ? prog->GLName() : 0;
 
     if (prog && !prog->LinkStatus())
         return ErrorInvalidOperation("useProgram: program was not linked successfully");
 
     gl->fUseProgram(progname);
 
     mCurrentProgram = prog;
 }
 
 void
 WebGLContext::ValidateProgram(WebGLProgram *prog)
 {
-    if (!IsContextStable())
+    if (IsContextLost())
         return;
 
     if (!ValidateObject("validateProgram", prog))
         return;
 
     MakeContextCurrent();
 
 #ifdef XP_MACOSX
     // see bug 593867 for NVIDIA and bug 657201 for ATI. The latter is confirmed with Mac OS 10.6.7
     if (gl->WorkAroundDriverBugs()) {
         GenerateWarning("validateProgram: implemented as a no-operation on Mac to work around crashes");
         return;
     }
 #endif
 
-    WebGLuint progname = prog->GLName();
+    GLuint progname = prog->GLName();
     gl->fValidateProgram(progname);
 }
 
 already_AddRefed<WebGLFramebuffer>
 WebGLContext::CreateFramebuffer()
 {
-    if (!IsContextStable())
+    if (IsContextLost())
         return nullptr;
     nsRefPtr<WebGLFramebuffer> globj = new WebGLFramebuffer(this);
     return globj.forget();
 }
 
 already_AddRefed<WebGLRenderbuffer>
 WebGLContext::CreateRenderbuffer()
 {
-    if (!IsContextStable())
+    if (IsContextLost())
         return nullptr;
     nsRefPtr<WebGLRenderbuffer> globj = new WebGLRenderbuffer(this);
     return globj.forget();
 }
 
 void
-WebGLContext::Viewport(WebGLint x, WebGLint y, WebGLsizei width, WebGLsizei height)
+WebGLContext::Viewport(GLint x, GLint y, GLsizei width, GLsizei height)
 {
-    if (!IsContextStable())
+    if (IsContextLost())
         return;
 
     if (width < 0 || height < 0)
         return ErrorInvalidValue("viewport: negative size");
 
     MakeContextCurrent();
     gl->fViewport(x, y, width, height);
 }
 
 void
 WebGLContext::CompileShader(WebGLShader *shader)
 {
-    if (!IsContextStable())
+    if (IsContextLost())
         return;
 
     if (!ValidateObject("compileShader", shader))
         return;
 
-    WebGLuint shadername = shader->GLName();
+    GLuint shadername = shader->GLName();
 
     shader->SetCompileStatus(false);
 
     MakeContextCurrent();
 
     ShShaderOutput targetShaderSourceLanguage = gl->IsGLES2() ? SH_ESSL_OUTPUT : SH_GLSL_OUTPUT;
     bool useShaderSourceTranslation = true;
 
@@ -3274,21 +3240,21 @@ WebGLContext::CompileShader(WebGLShader 
         gl->fCompileShader(shadername);
         GLint ok;
         gl->fGetShaderiv(shadername, LOCAL_GL_COMPILE_STATUS, &ok);
         shader->SetCompileStatus(ok);
     }
 }
 
 void
-WebGLContext::CompressedTexImage2D(WebGLenum target, WebGLint level, WebGLenum internalformat,
-                                   WebGLsizei width, WebGLsizei height, WebGLint border,
+WebGLContext::CompressedTexImage2D(GLenum target, GLint level, GLenum internalformat,
+                                   GLsizei width, GLsizei height, GLint border,
                                    const ArrayBufferView& view)
 {
-    if (!IsContextStable()) {
+    if (IsContextLost()) {
         return;
     }
 
     if (!ValidateTexImage2DTarget(target, width, height, "compressedTexImage2D")) {
         return;
     }
 
     WebGLTexture *tex = activeBoundTextureForTarget(target);
@@ -3314,21 +3280,21 @@ WebGLContext::CompressedTexImage2D(WebGL
 
     gl->fCompressedTexImage2D(target, level, internalformat, width, height, border, byteLength, view.Data());
     tex->SetImageInfo(target, level, width, height, internalformat, LOCAL_GL_UNSIGNED_BYTE);
 
     ReattachTextureToAnyFramebufferToWorkAroundBugs(tex, level);
 }
 
 void
-WebGLContext::CompressedTexSubImage2D(WebGLenum target, WebGLint level, WebGLint xoffset,
-                                      WebGLint yoffset, WebGLsizei width, WebGLsizei height,
-                                      WebGLenum format, const ArrayBufferView& view)
+WebGLContext::CompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset,
+                                      GLint yoffset, GLsizei width, GLsizei height,
+                                      GLenum format, const ArrayBufferView& view)
 {
-    if (!IsContextStable()) {
+    if (IsContextLost()) {
         return;
     }
 
     switch (target) {
         case LOCAL_GL_TEXTURE_2D:
         case LOCAL_GL_TEXTURE_CUBE_MAP_POSITIVE_X:
         case LOCAL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
         case LOCAL_GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
@@ -3414,25 +3380,25 @@ WebGLContext::CompressedTexSubImage2D(We
     }
 
     gl->fCompressedTexSubImage2D(target, level, xoffset, yoffset, width, height, format, byteLength, view.Data());
 
     return;
 }
 
 JS::Value
-WebGLContext::GetShaderParameter(WebGLShader *shader, WebGLenum pname)
+WebGLContext::GetShaderParameter(WebGLShader *shader, GLenum pname)
 {
-    if (!IsContextStable())
+    if (IsContextLost())
         return JS::NullValue();
 
     if (!ValidateObject("getShaderParameter: shader", shader))
         return JS::NullValue();
 
-    WebGLuint shadername = shader->GLName();
+    GLuint shadername = shader->GLName();
 
     MakeContextCurrent();
 
     switch (pname) {
         case LOCAL_GL_SHADER_TYPE:
         {
             GLint i = 0;
             gl->fGetShaderiv(shadername, pname, &i);
@@ -3465,33 +3431,33 @@ WebGLContext::GetShaderInfoLog(WebGLShad
         retval.SetIsVoid(true);
     else
         CopyASCIItoUTF16(s, retval);
 }
 
 void
 WebGLContext::GetShaderInfoLog(WebGLShader *shader, nsACString& retval)
 {
-    if (!IsContextStable())
+    if (IsContextLost())
     {
         retval.SetIsVoid(true);
         return;
     }
 
     if (!ValidateObject("getShaderInfoLog: shader", shader))
         return;
 
     retval = shader->TranslationLog();
     if (!retval.IsVoid()) {
         return;
     }
 
     MakeContextCurrent();
 
-    WebGLuint shadername = shader->GLName();
+    GLuint shadername = shader->GLName();
     GLint k = -1;
     gl->fGetShaderiv(shadername, LOCAL_GL_INFO_LOG_LENGTH, &k);
     if (k == -1) {
         // XXX GL Error? should never happen.
         return;
     }
 
     if (k == 0) {
@@ -3500,19 +3466,19 @@ WebGLContext::GetShaderInfoLog(WebGLShad
     }
 
     retval.SetCapacity(k);
     gl->fGetShaderInfoLog(shadername, k, &k, (char*) retval.BeginWriting());
     retval.SetLength(k);
 }
 
 already_AddRefed<WebGLShaderPrecisionFormat>
-WebGLContext::GetShaderPrecisionFormat(WebGLenum shadertype, WebGLenum precisiontype)
+WebGLContext::GetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype)
 {
-    if (!IsContextStable())
+    if (IsContextLost())
         return nullptr;
 
     switch (shadertype) {
         case LOCAL_GL_FRAGMENT_SHADER:
         case LOCAL_GL_VERTEX_SHADER:
             break;
         default:
             ErrorInvalidEnumInfo("getShaderPrecisionFormat: shadertype", shadertype);
@@ -3550,32 +3516,32 @@ WebGLContext::GetShaderPrecisionFormat(W
     nsRefPtr<WebGLShaderPrecisionFormat> retShaderPrecisionFormat
         = new WebGLShaderPrecisionFormat(this, range[0], range[1], precision);
     return retShaderPrecisionFormat.forget();
 }
 
 void
 WebGLContext::GetShaderSource(WebGLShader *shader, nsAString& retval)
 {
-    if (!IsContextStable())
+    if (IsContextLost())
     {
         retval.SetIsVoid(true);
         return;
     }
 
     if (!ValidateObject("getShaderSource: shader", shader))
         return;
 
     retval.Assign(shader->Source());
 }
 
 void
 WebGLContext::ShaderSource(WebGLShader *shader, const nsAString& source)
 {
-    if (!IsContextStable())
+    if (IsContextLost())
         return;
 
     if (!ValidateObject("shaderSource: shader", shader))
         return;
 
     // We're storing an actual instance of StripComments because, if we don't, the 
     // cleanSource nsAString instance will be destroyed before the reference is
     // actually used.
@@ -3621,20 +3587,20 @@ GLenum WebGLContext::CheckedTexImage2D(G
         return error;
     } else {
         gl->fTexImage2D(target, level, internalFormat, width, height, border, format, type, data);
         return LOCAL_GL_NO_ERROR;
     }
 }
 
 void
-WebGLContext::TexImage2D_base(WebGLenum target, WebGLint level, WebGLenum internalformat,
-                              WebGLsizei width, WebGLsizei height, WebGLsizei srcStrideOrZero,
-                              WebGLint border,
-                              WebGLenum format, WebGLenum type,
+WebGLContext::TexImage2D_base(GLenum target, GLint level, GLenum internalformat,
+                              GLsizei width, GLsizei height, GLsizei srcStrideOrZero,
+                              GLint border,
+                              GLenum format, GLenum type,
                               void *data, uint32_t byteLength,
                               int jsArrayType, // a TypedArray format enum, or -1 if not relevant
                               WebGLTexelFormat srcFormat, bool srcPremultiplied)
 {
     if (!ValidateTexImage2DTarget(target, width, height, "texImage2D")) {
         return;
     }
 
@@ -3766,57 +3732,57 @@ WebGLContext::TexImage2D_base(WebGLenum 
     }
 
     tex->SetImageInfo(target, level, width, height, format, type);
 
     ReattachTextureToAnyFramebufferToWorkAroundBugs(tex, level);
 }
 
 void
-WebGLContext::TexImage2D(WebGLenum target, WebGLint level,
-                         WebGLenum internalformat, WebGLsizei width,
-                         WebGLsizei height, WebGLint border, WebGLenum format,
-                         WebGLenum type, const Nullable<ArrayBufferView> &pixels, ErrorResult& rv)
+WebGLContext::TexImage2D(GLenum target, GLint level,
+                         GLenum internalformat, GLsizei width,
+                         GLsizei height, GLint border, GLenum format,
+                         GLenum type, const Nullable<ArrayBufferView> &pixels, ErrorResult& rv)
 {
-    if (!IsContextStable())
+    if (IsContextLost())
         return;
 
     return TexImage2D_base(target, level, internalformat, width, height, 0, border, format, type,
                            pixels.IsNull() ? 0 : pixels.Value().Data(),
                            pixels.IsNull() ? 0 : pixels.Value().Length(),
                            pixels.IsNull() ? -1 : (int)JS_GetArrayBufferViewType(pixels.Value().Obj()),
                            WebGLTexelConversions::Auto, false);
 }
 
 void
-WebGLContext::TexImage2D(WebGLenum target, WebGLint level,
-                         WebGLenum internalformat, WebGLenum format,
-                         WebGLenum type, ImageData* pixels, ErrorResult& rv)
+WebGLContext::TexImage2D(GLenum target, GLint level,
+                         GLenum internalformat, GLenum format,
+                         GLenum type, ImageData* pixels, ErrorResult& rv)
 {
-    if (!IsContextStable())
+    if (IsContextLost())
         return;
 
     if (!pixels) {
         // Spec says to generate an INVALID_VALUE error
         return ErrorInvalidValue("texImage2D: null ImageData");
     }
     
     Uint8ClampedArray arr(pixels->GetDataObject());
     return TexImage2D_base(target, level, internalformat, pixels->Width(),
                            pixels->Height(), 4*pixels->Width(), 0,
                            format, type, arr.Data(), arr.Length(), -1,
                            WebGLTexelConversions::RGBA8, false);
 }
 
 
 void
-WebGLContext::TexSubImage2D_base(WebGLenum target, WebGLint level,
-                                 WebGLint xoffset, WebGLint yoffset,
-                                 WebGLsizei width, WebGLsizei height, WebGLsizei srcStrideOrZero,
-                                 WebGLenum format, WebGLenum type,
+WebGLContext::TexSubImage2D_base(GLenum target, GLint level,
+                                 GLint xoffset, GLint yoffset,
+                                 GLsizei width, GLsizei height, GLsizei srcStrideOrZero,
+                                 GLenum format, GLenum type,
                                  void *pixels, uint32_t byteLength,
                                  int jsArrayType,
                                  WebGLTexelFormat srcFormat, bool srcPremultiplied)
 {
     switch (target) {
         case LOCAL_GL_TEXTURE_2D:
         case LOCAL_GL_TEXTURE_CUBE_MAP_POSITIVE_X:
         case LOCAL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
@@ -3915,43 +3881,43 @@ WebGLContext::TexSubImage2D_base(WebGLen
                     actualSrcFormat, srcPremultiplied,
                     dstFormat, mPixelStorePremultiplyAlpha, dstTexelSize);
 
         gl->fTexSubImage2D(target, level, xoffset, yoffset, width, height, format, type, convertedData);
     }
 }
 
 void
-WebGLContext::TexSubImage2D(WebGLenum target, WebGLint level,
-                            WebGLint xoffset, WebGLint yoffset,
-                            WebGLsizei width, WebGLsizei height,
-                            WebGLenum format, WebGLenum type,
+WebGLContext::TexSubImage2D(GLenum target, GLint level,
+                            GLint xoffset, GLint yoffset,
+                            GLsizei width, GLsizei height,
+                            GLenum format, GLenum type,
                             const Nullable<ArrayBufferView> &pixels,
                             ErrorResult& rv)
 {
-    if (!IsContextStable())
+    if (IsContextLost())
         return;
 
     if (pixels.IsNull())
         return ErrorInvalidValue("texSubImage2D: pixels must not be null!");
 
     return TexSubImage2D_base(target, level, xoffset, yoffset,
                               width, height, 0, format, type,
                               pixels.Value().Data(), pixels.Value().Length(),
                               JS_GetArrayBufferViewType(pixels.Value().Obj()),
                               WebGLTexelConversions::Auto, false);
 }
 
 void
-WebGLContext::TexSubImage2D(WebGLenum target, WebGLint level,
-                            WebGLint xoffset, WebGLint yoffset,
-                            WebGLenum format, WebGLenum type, ImageData* pixels,
+WebGLContext::TexSubImage2D(GLenum target, GLint level,
+                            GLint xoffset, GLint yoffset,
+                            GLenum format, GLenum type, ImageData* pixels,
                             ErrorResult& rv)
 {
-    if (!IsContextStable())
+    if (IsContextLost())
         return;
 
     if (!pixels)
         return ErrorInvalidValue("texSubImage2D: pixels must not be null!");
 
     Uint8ClampedArray arr(pixels->GetDataObject());
     return TexSubImage2D_base(target, level, xoffset, yoffset,
                               pixels->Width(), pixels->Height(),
@@ -3959,38 +3925,38 @@ WebGLContext::TexSubImage2D(WebGLenum ta
                               arr.Data(), arr.Length(),
                               -1,
                               WebGLTexelConversions::RGBA8, false);
 }
 
 bool
 WebGLContext::LoseContext()
 {
-    if (!IsContextStable())
+    if (IsContextLost())
         return false;
 
     ForceLoseContext();
 
     return true;
 }
 
 bool
 WebGLContext::RestoreContext()
 {
-    if (IsContextStable() || !mAllowRestore) {
+    if (!IsContextLost() || !mAllowRestore) {
         return false;
     }
 
     ForceRestoreContext();
 
     return true;
 }
 
 bool
-BaseTypeAndSizeFromUniformType(WebGLenum uType, WebGLenum *baseType, WebGLint *unitSize)
+BaseTypeAndSizeFromUniformType(GLenum uType, GLenum *baseType, GLint *unitSize)
 {
     switch (uType) {
         case LOCAL_GL_INT:
         case LOCAL_GL_INT_VEC2:
         case LOCAL_GL_INT_VEC3:
         case LOCAL_GL_INT_VEC4:
         case LOCAL_GL_SAMPLER_2D:
         case LOCAL_GL_SAMPLER_CUBE:
@@ -4121,18 +4087,18 @@ WebGLTexelFormat mozilla::GetWebGLTexelF
                 return WebGLTexelConversions::RGB565;
             default:
                 NS_ABORT_IF_FALSE(false, "Coding mistake?! Should never reach this point.");
                 return WebGLTexelConversions::BadFormat;
         }
     }
 }
 
-WebGLenum
-InternalFormatForFormatAndType(WebGLenum format, WebGLenum type, bool isGLES2)
+GLenum
+InternalFormatForFormatAndType(GLenum format, GLenum type, bool isGLES2)
 {
     // ES2 requires that format == internalformat; floating-point is
     // indicated purely by the type that's loaded.  For desktop GL, we
     // have to specify a floating point internal format.
     if (isGLES2)
         return format;
 
     if (format == LOCAL_GL_DEPTH_COMPONENT) {
@@ -4174,17 +4140,17 @@ InternalFormatForFormatAndType(WebGLenum
     }
 
     NS_ASSERTION(false, "Coding mistake -- bad format/type passed?");
     return 0;
 }
 
 void
 WebGLContext::ReattachTextureToAnyFramebufferToWorkAroundBugs(WebGLTexture *tex,
-                                                              WebGLint level)
+                                                              GLint level)
 {
     MOZ_ASSERT(tex);
 
     if (!gl->WorkAroundDriverBugs())
         return;
 
     if (!mIsMesa)
         return;
@@ -4223,8 +4189,56 @@ WebGLContext::ReattachTextureToAnyFrameb
             framebuffer->FramebufferTexture2D(
               LOCAL_GL_FRAMEBUFFER, LOCAL_GL_DEPTH_STENCIL_ATTACHMENT,
               tex->Target(), tex, level);
         }
     }
 
     BindFramebuffer(LOCAL_GL_FRAMEBUFFER, curFB);
 }
+
+void
+WebGLContext::BlendColor(GLclampf r, GLclampf g, GLclampf b, GLclampf a) {
+    if (IsContextLost())
+        return;
+    MakeContextCurrent();
+    gl->fBlendColor(r, g, b, a);
+}
+
+void
+WebGLContext::Flush() {
+    if (IsContextLost())
+        return;
+    MakeContextCurrent();
+    gl->fFlush();
+}
+
+void
+WebGLContext::Finish() {
+    if (IsContextLost())
+        return;
+    MakeContextCurrent();
+    gl->fFinish();
+}
+
+void
+WebGLContext::LineWidth(GLfloat width) {
+    if (IsContextLost())
+        return;
+    MakeContextCurrent();
+    gl->fLineWidth(width);
+}
+
+void
+WebGLContext::PolygonOffset(GLfloat factor, GLfloat units) {
+    if (IsContextLost())
+        return;
+    MakeContextCurrent();
+    gl->fPolygonOffset(factor, units);
+}
+
+void
+WebGLContext::SampleCoverage(GLclampf value, WebGLboolean invert) {
+    if (IsContextLost())
+        return;
+    MakeContextCurrent();
+    gl->fSampleCoverage(value, invert);
+}
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/content/canvas/src/WebGLContextLossTimer.cpp
@@ -0,0 +1,40 @@
+/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* 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/. */
+
+#include "WebGLContext.h"
+
+using namespace mozilla;
+
+/* static */ void
+WebGLContext::RobustnessTimerCallbackStatic(nsITimer* timer, void *thisPointer) {
+    static_cast<WebGLContext*>(thisPointer)->RobustnessTimerCallback(timer);
+}
+
+void
+WebGLContext::SetupContextLossTimer() {
+    // If the timer was already running, don't restart it here. Instead,
+    // wait until the previous call is done, then fire it one more time.
+    // This is an optimization to prevent unnecessary cross-communication
+    // between threads.
+    if (mContextLossTimerRunning) {
+        mDrawSinceContextLossTimerSet = true;
+        return;
+    }
+
+    mContextRestorer->InitWithFuncCallback(RobustnessTimerCallbackStatic,
+                                            static_cast<void*>(this),
+                                            1000,
+                                            nsITimer::TYPE_ONE_SHOT);
+    mContextLossTimerRunning = true;
+    mDrawSinceContextLossTimerSet = false;
+}
+
+void
+WebGLContext::TerminateContextLossTimer() {
+    if (mContextLossTimerRunning) {
+        mContextRestorer->Cancel();
+        mContextLossTimerRunning = false;
+    }
+}
--- a/content/canvas/src/WebGLContextState.cpp
+++ b/content/canvas/src/WebGLContextState.cpp
@@ -7,24 +7,25 @@
 #include "WebGLContextUtils.h"
 #include "WebGLBuffer.h"
 #include "WebGLShader.h"
 #include "WebGLProgram.h"
 #include "WebGLFramebuffer.h"
 #include "WebGLRenderbuffer.h"
 #include "WebGLTexture.h"
 #include "WebGLVertexArray.h"
+#include "GLContext.h"
 
 using namespace mozilla;
 using namespace dom;
 
 void
-WebGLContext::Disable(WebGLenum cap)
+WebGLContext::Disable(GLenum cap)
 {
-    if (!IsContextStable())
+    if (IsContextLost())
         return;
 
     if (!ValidateCapabilityEnum(cap, "disable"))
         return;
 
     realGLboolean* trackingSlot = GetStateTrackingSlot(cap);
 
     if (trackingSlot)
@@ -32,19 +33,19 @@ WebGLContext::Disable(WebGLenum cap)
         *trackingSlot = 0;
     }
 
     MakeContextCurrent();
     gl->fDisable(cap);
 }
 
 void
-WebGLContext::Enable(WebGLenum cap)
+WebGLContext::Enable(GLenum cap)
 {
-    if (!IsContextStable())
+    if (IsContextLost())
         return;
 
     if (!ValidateCapabilityEnum(cap, "enable"))
         return;
 
     realGLboolean* trackingSlot = GetStateTrackingSlot(cap);
 
     if (trackingSlot)
@@ -64,19 +65,19 @@ StringValue(JSContext* cx, const char* c
         rv.Throw(NS_ERROR_OUT_OF_MEMORY);
         return JS::NullValue();
     }
 
     return JS::StringValue(str);
 }
 
 JS::Value
-WebGLContext::GetParameter(JSContext* cx, WebGLenum pname, ErrorResult& rv)
+WebGLContext::GetParameter(JSContext* cx, GLenum pname, ErrorResult& rv)
 {
-    if (!IsContextStable())
+    if (IsContextLost())
         return JS::NullValue();
 
     MakeContextCurrent();
 
     if (MinCapabilityMode()) {
         switch(pname) {
             //
             // Single-value params
@@ -122,17 +123,17 @@ WebGLContext::GetParameter(JSContext* cx
         {
             return JS::Int32Value(mGLMaxColorAttachments);
         }
         else if (pname == LOCAL_GL_MAX_DRAW_BUFFERS)
         {
             return JS::Int32Value(mGLMaxDrawBuffers);
         }
         else if (pname >= LOCAL_GL_DRAW_BUFFER0 &&
-                 pname < WebGLenum(LOCAL_GL_DRAW_BUFFER0 + mGLMaxDrawBuffers))
+                 pname < GLenum(LOCAL_GL_DRAW_BUFFER0 + mGLMaxDrawBuffers))
         {
             if (mBoundFramebuffer) {
                 GLint iv = 0;
                 gl->fGetIntegerv(pname, &iv);
                 return JS::Int32Value(iv);
             }
 
             GLint iv = 0;
@@ -479,19 +480,19 @@ WebGLContext::GetParameter(JSContext* cx
         default:
             ErrorInvalidEnumInfo("getParameter: parameter", pname);
     }
 
     return JS::NullValue();
 }
 
 JS::Value
-WebGLContext::GetParameterIndexed(JSContext* cx, WebGLenum pname, WebGLuint index)
+WebGLContext::GetParameterIndexed(JSContext* cx, GLenum pname, GLuint index)
 {
-    if (!IsContextStable())
+    if (IsContextLost())
         return JS::NullValue();
 
     MakeContextCurrent();
 
     switch (pname) {
         case LOCAL_GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
         {
             if (index >= mGLMaxTransformFeedbackSeparateAttribs) {
@@ -505,30 +506,30 @@ WebGLContext::GetParameterIndexed(JSCont
             break;
     }
 
     ErrorInvalidEnumInfo("getParameterIndexed: parameter", pname);
     return JS::NullValue();
 }
 
 bool
-WebGLContext::IsEnabled(WebGLenum cap)
+WebGLContext::IsEnabled(GLenum cap)
 {
-    if (!IsContextStable())
+    if (IsContextLost())
         return false;
 
     if (!ValidateCapabilityEnum(cap, "isEnabled"))
         return false;
 
     MakeContextCurrent();
     return gl->fIsEnabled(cap);
 }
 
 bool
-WebGLContext::ValidateCapabilityEnum(WebGLenum cap, const char* info)
+WebGLContext::ValidateCapabilityEnum(GLenum cap, const char* info)
 {
     switch (cap) {
         case LOCAL_GL_BLEND:
         case LOCAL_GL_CULL_FACE:
         case LOCAL_GL_DEPTH_TEST:
         case LOCAL_GL_DITHER:
         case LOCAL_GL_POLYGON_OFFSET_FILL:
         case LOCAL_GL_SAMPLE_ALPHA_TO_COVERAGE:
@@ -540,17 +541,17 @@ WebGLContext::ValidateCapabilityEnum(Web
             return IsWebGL2();
         default:
             ErrorInvalidEnumInfo(info, cap);
             return false;
     }
 }
 
 realGLboolean*
-WebGLContext::GetStateTrackingSlot(WebGLenum cap)
+WebGLContext::GetStateTrackingSlot(GLenum cap)
 {
     switch (cap) {
         case LOCAL_GL_SCISSOR_TEST:
             return &mScissorTestEnabled;
         case LOCAL_GL_DITHER:
             return &mDitherEnabled;
         case LOCAL_GL_RASTERIZER_DISCARD:
             return &mRasterizerDiscardEnabled;
--- a/content/canvas/src/WebGLContextUtils.cpp
+++ b/content/canvas/src/WebGLContextUtils.cpp
@@ -1,16 +1,17 @@
 /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
 /* 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/. */
 
 #include <stdarg.h>
 
 #include "WebGLContext.h"
+#include "GLContext.h"
 
 #include "prprf.h"
 
 #include "jsapi.h"
 #include "nsIScriptSecurityManager.h"
 #include "nsServiceManagerUtils.h"
 #include "nsIVariant.h"
 #include "nsCxPusher.h"
@@ -50,52 +51,62 @@ WebGLContext::GenerateWarning(const char
     JS_ReportWarning(cx, "WebGL: %s", buf);
     if (!ShouldGenerateWarnings()) {
         JS_ReportWarning(cx,
             "WebGL: No further warnings will be reported for this WebGL context "
             "(already reported %d warnings)", mAlreadyGeneratedWarnings);
     }
 }
 
+bool
+WebGLContext::ShouldGenerateWarnings() const
+{
+    if (mMaxWarnings == -1) {
+        return true;
+    }
+
+    return mAlreadyGeneratedWarnings < mMaxWarnings;
+}
+
 CheckedUint32
-WebGLContext::GetImageSize(WebGLsizei height, 
-                           WebGLsizei width, 
+WebGLContext::GetImageSize(GLsizei height, 
+                           GLsizei width, 
                            uint32_t pixelSize,
                            uint32_t packOrUnpackAlignment)
 {
     CheckedUint32 checked_plainRowSize = CheckedUint32(width) * pixelSize;
 
     // alignedRowSize = row size rounded up to next multiple of packAlignment
     CheckedUint32 checked_alignedRowSize = RoundedToNextMultipleOf(checked_plainRowSize, packOrUnpackAlignment);
 
     // if height is 0, we don't need any memory to store this; without this check, we'll get an overflow
     CheckedUint32 checked_neededByteLength
         = height <= 0 ? 0 : (height-1) * checked_alignedRowSize + checked_plainRowSize;
 
     return checked_neededByteLength;
 }
 
 void
-WebGLContext::SynthesizeGLError(WebGLenum err)
+WebGLContext::SynthesizeGLError(GLenum err)
 {
     // If there is already a pending error, don't overwrite it;
     // but if there isn't, then we need to check for a gl error
     // that may have occurred before this one and use that code
     // instead.
     
     MakeContextCurrent();
 
     UpdateWebGLErrorAndClearGLError();
 
     if (!mWebGLError)
         mWebGLError = err;
 }
 
 void
-WebGLContext::SynthesizeGLError(WebGLenum err, const char *fmt, ...)
+WebGLContext::SynthesizeGLError(GLenum err, const char *fmt, ...)
 {
     va_list va;
     va_start(va, fmt);
     GenerateWarning(fmt, va);
     va_end(va);
 
     return SynthesizeGLError(err);
 }
@@ -107,16 +118,22 @@ WebGLContext::ErrorInvalidEnum(const cha
     va_start(va, fmt);
     GenerateWarning(fmt, va);
     va_end(va);
 
     return SynthesizeGLError(LOCAL_GL_INVALID_ENUM);
 }
 
 void
+WebGLContext::ErrorInvalidEnumInfo(const char *info, GLenum enumvalue)
+{
+    return ErrorInvalidEnum("%s: invalid enum value 0x%x", info, enumvalue);
+}
+
+void
 WebGLContext::ErrorInvalidOperation(const char *fmt, ...)
 {
     va_list va;
     va_start(va, fmt);
     GenerateWarning(fmt, va);
     va_end(va);
 
     return SynthesizeGLError(LOCAL_GL_INVALID_OPERATION);
@@ -203,8 +220,20 @@ WebGLContext::IsTextureFormatCompressed(
         case LOCAL_GL_COMPRESSED_RGBA_PVRTC_2BPPV1:
             return true;
     }
 
     NS_NOTREACHED("Invalid WebGL texture format?");
     NS_ABORT();
     return false;
 }
+
+void
+WebGLContext::UpdateWebGLErrorAndClearGLError(GLenum *currentGLError)
+{
+    // get and clear GL error in ALL cases
+    GLenum error = gl->GetAndClearError();
+    if (currentGLError)
+        *currentGLError = error;
+    // only store in mWebGLError if is hasn't already recorded an error
+    if (!mWebGLError)
+        mWebGLError = error;
+}
--- a/content/canvas/src/WebGLContextValidate.cpp
+++ b/content/canvas/src/WebGLContextValidate.cpp
@@ -8,16 +8,17 @@
 #include "WebGLVertexAttribData.h"
 #include "WebGLShader.h"
 #include "WebGLProgram.h"
 #include "WebGLUniformLocation.h"
 #include "WebGLFramebuffer.h"
 #include "WebGLRenderbuffer.h"
 #include "WebGLTexture.h"
 #include "WebGLVertexArray.h"
+#include "GLContext.h"
 
 #include "mozilla/CheckedInt.h"
 #include "mozilla/Preferences.h"
 #include "mozilla/Services.h"
 
 #include "jsfriendapi.h"
 
 #include "angle/ShaderLang.h"
@@ -103,17 +104,17 @@ WebGLProgram::UpdateInfo()
         GLint attrLoc = mContext->gl->fGetAttribLocation(mGLName, attrName);
         MOZ_ASSERT(attrLoc >= 0);
         mActiveAttribMap.insert(std::make_pair(attrLoc, nsCString(attrName)));
     }
 
     return true;
 }
 
-bool WebGLContext::ValidateBlendEquationEnum(WebGLenum mode, const char *info)
+bool WebGLContext::ValidateBlendEquationEnum(GLenum mode, const char *info)
 {
     switch (mode) {
         case LOCAL_GL_FUNC_ADD:
         case LOCAL_GL_FUNC_SUBTRACT:
         case LOCAL_GL_FUNC_REVERSE_SUBTRACT:
             return true;
         case LOCAL_GL_MIN:
         case LOCAL_GL_MAX:
@@ -125,17 +126,17 @@ bool WebGLContext::ValidateBlendEquation
         default:
             break;
     }
 
     ErrorInvalidEnumInfo(info, mode);
     return false;
 }
 
-bool WebGLContext::ValidateBlendFuncDstEnum(WebGLenum factor, const char *info)
+bool WebGLContext::ValidateBlendFuncDstEnum(GLenum factor, const char *info)
 {
     switch (factor) {
         case LOCAL_GL_ZERO:
         case LOCAL_GL_ONE:
         case LOCAL_GL_SRC_COLOR:
         case LOCAL_GL_ONE_MINUS_SRC_COLOR:
         case LOCAL_GL_DST_COLOR:
         case LOCAL_GL_ONE_MINUS_DST_COLOR:
@@ -149,25 +150,25 @@ bool WebGLContext::ValidateBlendFuncDstE
         case LOCAL_GL_ONE_MINUS_CONSTANT_ALPHA:
             return true;
         default:
             ErrorInvalidEnumInfo(info, factor);
             return false;
     }
 }
 
-bool WebGLContext::ValidateBlendFuncSrcEnum(WebGLenum factor, const char *info)
+bool WebGLContext::ValidateBlendFuncSrcEnum(GLenum factor, const char *info)
 {
     if (factor == LOCAL_GL_SRC_ALPHA_SATURATE)
         return true;
     else
         return ValidateBlendFuncDstEnum(factor, info);
 }
 
-bool WebGLContext::ValidateBlendFuncEnumsCompatibility(WebGLenum sfactor, WebGLenum dfactor, const char *info)
+bool WebGLContext::ValidateBlendFuncEnumsCompatibility(GLenum sfactor, GLenum dfactor, const char *info)
 {
     bool sfactorIsConstantColor = sfactor == LOCAL_GL_CONSTANT_COLOR ||
                                     sfactor == LOCAL_GL_ONE_MINUS_CONSTANT_COLOR;
     bool sfactorIsConstantAlpha = sfactor == LOCAL_GL_CONSTANT_ALPHA ||
                                     sfactor == LOCAL_GL_ONE_MINUS_CONSTANT_ALPHA;
     bool dfactorIsConstantColor = dfactor == LOCAL_GL_CONSTANT_COLOR ||
                                     dfactor == LOCAL_GL_ONE_MINUS_CONSTANT_COLOR;
     bool dfactorIsConstantAlpha = dfactor == LOCAL_GL_CONSTANT_ALPHA ||
@@ -176,29 +177,29 @@ bool WebGLContext::ValidateBlendFuncEnum
          (dfactorIsConstantColor && sfactorIsConstantAlpha) ) {
         ErrorInvalidOperation("%s are mutually incompatible, see section 6.8 in the WebGL 1.0 spec", info);
         return false;
     } else {
         return true;
     }
 }
 
-bool WebGLContext::ValidateTextureTargetEnum(WebGLenum target, const char *info)
+bool WebGLContext::ValidateTextureTargetEnum(GLenum target, const char *info)
 {
     switch (target) {
         case LOCAL_GL_TEXTURE_2D:
         case LOCAL_GL_TEXTURE_CUBE_MAP:
             return true;
         default:
             ErrorInvalidEnumInfo(info, target);
             return false;
     }
 }
 
-bool WebGLContext::ValidateComparisonEnum(WebGLenum target, const char *info)
+bool WebGLContext::ValidateComparisonEnum(GLenum target, const char *info)
 {
     switch (target) {
         case LOCAL_GL_NEVER:
         case LOCAL_GL_LESS:
         case LOCAL_GL_LEQUAL:
         case LOCAL_GL_GREATER:
         case LOCAL_GL_GEQUAL:
         case LOCAL_GL_EQUAL:
@@ -206,17 +207,17 @@ bool WebGLContext::ValidateComparisonEnu
         case LOCAL_GL_ALWAYS:
             return true;
         default:
             ErrorInvalidEnumInfo(info, target);
             return false;
     }
 }
 
-bool WebGLContext::ValidateStencilOpEnum(WebGLenum action, const char *info)
+bool WebGLContext::ValidateStencilOpEnum(GLenum action, const char *info)
 {
     switch (action) {
         case LOCAL_GL_KEEP:
         case LOCAL_GL_ZERO:
         case LOCAL_GL_REPLACE:
         case LOCAL_GL_INCR:
         case LOCAL_GL_INCR_WRAP:
         case LOCAL_GL_DECR:
@@ -224,30 +225,30 @@ bool WebGLContext::ValidateStencilOpEnum
         case LOCAL_GL_INVERT:
             return true;
         default:
             ErrorInvalidEnumInfo(info, action);
             return false;
     }
 }
 
-bool WebGLContext::ValidateFaceEnum(WebGLenum face, const char *info)
+bool WebGLContext::ValidateFaceEnum(GLenum face, const char *info)
 {
     switch (face) {
         case LOCAL_GL_FRONT:
         case LOCAL_GL_BACK:
         case LOCAL_GL_FRONT_AND_BACK:
             return true;
         default:
             ErrorInvalidEnumInfo(info, face);
             return false;
     }
 }
 
-bool WebGLContext::ValidateDrawModeEnum(WebGLenum mode, const char *info)
+bool WebGLContext::ValidateDrawModeEnum(GLenum mode, const char *info)
 {
     switch (mode) {
         case LOCAL_GL_TRIANGLES:
         case LOCAL_GL_TRIANGLE_STRIP:
         case LOCAL_GL_TRIANGLE_FAN:
         case LOCAL_GL_POINTS:
         case LOCAL_GL_LINE_STRIP:
         case LOCAL_GL_LINE_LOOP:
@@ -295,17 +296,17 @@ bool WebGLContext::ValidateGLSLString(co
              ErrorInvalidValue("%s: string contains the illegal character '%d'", info, string.CharAt(i));
              return false;
         }
     }
 
     return true;
 }
 
-bool WebGLContext::ValidateTexImage2DTarget(WebGLenum target, WebGLsizei width, WebGLsizei height,
+bool WebGLContext::ValidateTexImage2DTarget(GLenum target, GLsizei width, GLsizei height,
                                             const char* info)
 {
     switch (target) {
         case LOCAL_GL_TEXTURE_2D:
             break;
         case LOCAL_GL_TEXTURE_CUBE_MAP_POSITIVE_X:
         case LOCAL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
         case LOCAL_GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
@@ -320,19 +321,19 @@ bool WebGLContext::ValidateTexImage2DTar
         default:
             ErrorInvalidEnum("%s: invalid target enum 0x%x", info, target);
             return false;
     }
 
     return true;
 }
 
-bool WebGLContext::ValidateCompressedTextureSize(WebGLenum target, WebGLint level,
-                                                 WebGLenum format,
-                                                 WebGLsizei width, WebGLsizei height, uint32_t byteLength, const char* info)
+bool WebGLContext::ValidateCompressedTextureSize(GLenum target, GLint level,
+                                                 GLenum format,
+                                                 GLsizei width, GLsizei height, uint32_t byteLength, const char* info)
 {
     if (!ValidateLevelWidthHeightForTarget(target, level, width, height, info)) {
         return false;
     }
 
     // negative width and height must already have been handled above
     MOZ_ASSERT(width >= 0 && height >= 0);
 
@@ -403,27 +404,27 @@ bool WebGLContext::ValidateCompressedTex
                 return false;
             }
         }
     }
 
     return true;
 }
 
-bool WebGLContext::ValidateLevelWidthHeightForTarget(WebGLenum target, WebGLint level, WebGLsizei width,
-                                                     WebGLsizei height, const char* info)
+bool WebGLContext::ValidateLevelWidthHeightForTarget(GLenum target, GLint level, GLsizei width,
+                                                     GLsizei height, const char* info)
 {
-    WebGLsizei maxTextureSize = MaxTextureSizeForTarget(target);
+    GLsizei maxTextureSize = MaxTextureSizeForTarget(target);
 
     if (level < 0) {
         ErrorInvalidValue("%s: level must be >= 0", info);
         return false;
     }
 
-    WebGLsizei maxAllowedSize = maxTextureSize >> level;
+    GLsizei maxAllowedSize = maxTextureSize >> level;
 
     if (!maxAllowedSize) {
         ErrorInvalidValue("%s: 2^level exceeds maximum texture size", info);
         return false;
     }
 
     if (width < 0 || height < 0) {
         ErrorInvalidValue("%s: width and height must be >= 0", info);
@@ -433,17 +434,17 @@ bool WebGLContext::ValidateLevelWidthHei
     if (width > maxAllowedSize || height > maxAllowedSize) {
         ErrorInvalidValue("%s: the maximum texture size for level %d is %d", info, level, maxAllowedSize);
         return false;
     }
 
     return true;
 }
 
-uint32_t WebGLContext::GetBitsPerTexel(WebGLenum format, WebGLenum type)
+uint32_t WebGLContext::GetBitsPerTexel(GLenum format, GLenum type)
 {
     // If there is no defined format or type, we're not taking up any memory
     if (!format || !type) {
         return 0;
     }
 
     if (format == LOCAL_GL_DEPTH_COMPONENT) {
         if (type == LOCAL_GL_UNSIGNED_SHORT)
@@ -490,17 +491,17 @@ uint32_t WebGLContext::GetBitsPerTexel(W
     {
         return 16;
     }
 
     NS_ABORT();
     return 0;
 }
 
-bool WebGLContext::ValidateTexFormatAndType(WebGLenum format, WebGLenum type, int jsArrayType,
+bool WebGLContext::ValidateTexFormatAndType(GLenum format, GLenum type, int jsArrayType,
                                               uint32_t *texelSize, const char *info)
 {
     if (IsExtensionEnabled(WEBGL_depth_texture)) {
         if (format == LOCAL_GL_DEPTH_COMPONENT) {
             if (jsArrayType != -1) {
                 if ((type == LOCAL_GL_UNSIGNED_SHORT && jsArrayType != js::ArrayBufferView::TYPE_UINT16) ||
                     (type == LOCAL_GL_UNSIGNED_INT && jsArrayType != js::ArrayBufferView::TYPE_UINT32)) {
                     ErrorInvalidOperation("%s: invalid typed array type for given texture data type", info);
@@ -630,17 +631,17 @@ WebGLContext::ValidateUniformLocation(co
     if (mCurrentProgram->Generation() != location_object->ProgramGeneration()) {
         ErrorInvalidOperation("%s: This uniform location is obsolete since the program has been relinked", info);
         return false;
     }
     return true;
 }
 
 bool
-WebGLContext::ValidateSamplerUniformSetter(const char* info, WebGLUniformLocation *location, WebGLint value)
+WebGLContext::ValidateSamplerUniformSetter(const char* info, WebGLUniformLocation *location, GLint value)
 {
     if (location->Info().type != SH_SAMPLER_2D &&
         location->Info().type != SH_SAMPLER_CUBE)
     {
         return true;
     }
 
     if (value >= 0 && value < mGLMaxTextureUnits)
@@ -649,31 +650,31 @@ WebGLContext::ValidateSamplerUniformSett
     ErrorInvalidValue("%s: this uniform location is a sampler, but %d is not a valid texture unit",
                       info, value);
     return false;
 }
 
 bool
 WebGLContext::ValidateAttribArraySetter(const char* name, uint32_t cnt, uint32_t arrayLength)
 {
-    if (!IsContextStable()) {
+    if (IsContextLost()) {
         return false;
     }
     if (arrayLength < cnt) {
         ErrorInvalidOperation("%s: array must be >= %d elements", name, cnt);
         return false;
     }
     return true;
 }
 
 bool
 WebGLContext::ValidateUniformArraySetter(const char* name, uint32_t expectedElemSize, WebGLUniformLocation *location_object,
                                          GLint& location, uint32_t& numElementsToUpload, uint32_t arrayLength)
 {
-    if (!IsContextStable())
+    if (IsContextLost())
         return false;
     if (!ValidateUniformLocation(name, location_object))
         return false;
     location = location_object->Location();
     uint32_t uniformElemSize = location_object->ElementSize();
     if (expectedElemSize != uniformElemSize) {
         ErrorInvalidOperation("%s: this function expected a uniform of element size %d,"
                               " got a uniform of element size %d", name,
@@ -706,17 +707,17 @@ WebGLContext::ValidateUniformArraySetter
 }
 
 bool
 WebGLContext::ValidateUniformMatrixArraySetter(const char* name, int dim, WebGLUniformLocation *location_object,
                                               GLint& location, uint32_t& numElementsToUpload, uint32_t arrayLength,
                                               WebGLboolean aTranspose)
 {
     uint32_t expectedElemSize = (dim)*(dim);
-    if (!IsContextStable())
+    if (IsContextLost())
         return false;
     if (!ValidateUniformLocation(name, location_object))
         return false;
     location = location_object->Location();
     uint32_t uniformElemSize = location_object->ElementSize();
     if (expectedElemSize != uniformElemSize) {
         ErrorInvalidOperation("%s: this function expected a uniform of element size %d,"
                               " got a uniform of element size %d", name,
@@ -751,25 +752,25 @@ WebGLContext::ValidateUniformMatrixArray
     numElementsToUpload =
         std::min(info.arraySize, arrayLength / (expectedElemSize));
     return true;
 }
 
 bool
 WebGLContext::ValidateUniformSetter(const char* name, WebGLUniformLocation *location_object, GLint& location)
 {
-    if (!IsContextStable())
+    if (IsContextLost())
         return false;
     if (!ValidateUniformLocation(name, location_object))
         return false;
     location = location_object->Location();
     return true;
 }
 
-bool WebGLContext::ValidateAttribIndex(WebGLuint index, const char *info)
+bool WebGLContext::ValidateAttribIndex(GLuint index, const char *info)
 {
     return mBoundVertexArray->EnsureAttribIndex(index, info);
 }
 
 bool WebGLContext::ValidateStencilParamsForDrawCall()
 {
   const char *msg = "%s set different front and back stencil %s. Drawing in this configuration is not allowed.";
   if (mStencilRefFront != mStencilRefBack) {
--- a/content/canvas/src/WebGLContextVertexArray.cpp
+++ b/content/canvas/src/WebGLContextVertexArray.cpp
@@ -2,23 +2,24 @@
 /* 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/. */
 
 #include "WebGLContext.h"
 #include "WebGLBuffer.h"
 #include "WebGLVertexAttribData.h"
 #include "WebGLVertexArray.h"
+#include "GLContext.h"
 
 using namespace mozilla;
 
 void
 WebGLContext::BindVertexArray(WebGLVertexArray *array)
 {
-    if (!IsContextStable())
+    if (IsContextLost())
         return;
 
     if (!ValidateObjectAllowDeletedOrNull("bindVertexArrayObject", array))
         return;
 
     if (array && array->IsDeleted()) {
         /* http://www.khronos.org/registry/gles/extensions/OES/OES_vertex_array_object.txt
          * BindVertexArrayOES fails and an INVALID_OPERATION error is
@@ -43,33 +44,33 @@ WebGLContext::BindVertexArray(WebGLVerte
         gl->fBindVertexArray(0);
         mBoundVertexArray = mDefaultVertexArray;
     }
 }
 
 already_AddRefed<WebGLVertexArray>
 WebGLContext::CreateVertexArray()
 {
-    if (!IsContextStable())
+    if (IsContextLost())
         return nullptr;
 
     nsRefPtr<WebGLVertexArray> globj = new WebGLVertexArray(this);
 
     MakeContextCurrent();
     gl->fGenVertexArrays(1, &globj->mGLName);
 
     mVertexArrays.insertBack(globj);
 
     return globj.forget();
 }
 
 void
 WebGLContext::DeleteVertexArray(WebGLVertexArray *array)
 {
-    if (!IsContextStable())
+    if (IsContextLost())
         return;
 
     if (array == nullptr)
         return;
 
     if (array->IsDeleted())
         return;
 
@@ -77,17 +78,17 @@ WebGLContext::DeleteVertexArray(WebGLVer
         BindVertexArray(static_cast<WebGLVertexArray*>(nullptr));
 
     array->RequestDelete();
 }
 
 bool
 WebGLContext::IsVertexArray(WebGLVertexArray *array)
 {
-    if (!IsContextStable())
+    if (IsContextLost())
         return false;
 
     if (!array)
         return false;
 
     return ValidateObjectAllowDeleted("isVertexArray", array) &&
            !array->IsDeleted() &&
            array->HasEverBeenBound();
--- a/content/canvas/src/WebGLContextVertices.cpp
+++ b/content/canvas/src/WebGLContextVertices.cpp
@@ -8,27 +8,28 @@
 #include "WebGLVertexAttribData.h"
 #include "WebGLVertexArray.h"
 #include "WebGLTexture.h"
 #include "WebGLRenderbuffer.h"
 #include "WebGLFramebuffer.h"
 #include "WebGLUniformInfo.h"
 #include "WebGLShader.h"
 #include "WebGLProgram.h"
+#include "GLContext.h"
 
 using namespace mozilla;
 using namespace dom;
 
 // For a Tegra workaround.
 static const int MAX_DRAW_CALLS_SINCE_FLUSH = 100;
 
 void
-WebGLContext::VertexAttrib1f(WebGLuint index, WebGLfloat x0)
+WebGLContext::VertexAttrib1f(GLuint index, GLfloat x0)
 {
-    if (!IsContextStable())
+    if (IsContextLost())
         return;
 
     MakeContextCurrent();
 
     if (index) {
         gl->fVertexAttrib1f(index, x0);
     } else {
         mVertexAttrib0Vector[0] = x0;
@@ -36,19 +37,19 @@ WebGLContext::VertexAttrib1f(WebGLuint i
         mVertexAttrib0Vector[2] = 0;
         mVertexAttrib0Vector[3] = 1;
         if (gl->IsGLES2())
             gl->fVertexAttrib1f(index, x0);
     }
 }
 
 void
-WebGLContext::VertexAttrib2f(WebGLuint index, WebGLfloat x0, WebGLfloat x1)
+WebGLContext::VertexAttrib2f(GLuint index, GLfloat x0, GLfloat x1)
 {
-    if (!IsContextStable())
+    if (IsContextLost())
         return;
 
     MakeContextCurrent();
 
     if (index) {
         gl->fVertexAttrib2f(index, x0, x1);
     } else {
         mVertexAttrib0Vector[0] = x0;
@@ -56,19 +57,19 @@ WebGLContext::VertexAttrib2f(WebGLuint i
         mVertexAttrib0Vector[2] = 0;
         mVertexAttrib0Vector[3] = 1;
         if (gl->IsGLES2())
             gl->fVertexAttrib2f(index, x0, x1);
     }
 }
 
 void
-WebGLContext::VertexAttrib3f(WebGLuint index, WebGLfloat x0, WebGLfloat x1, WebGLfloat x2)
+WebGLContext::VertexAttrib3f(GLuint index, GLfloat x0, GLfloat x1, GLfloat x2)
 {
-    if (!IsContextStable())
+    if (IsContextLost())
         return;
 
     MakeContextCurrent();
 
     if (index) {
         gl->fVertexAttrib3f(index, x0, x1, x2);
     } else {
         mVertexAttrib0Vector[0] = x0;
@@ -76,20 +77,20 @@ WebGLContext::VertexAttrib3f(WebGLuint i
         mVertexAttrib0Vector[2] = x2;
         mVertexAttrib0Vector[3] = 1;
         if (gl->IsGLES2())
             gl->fVertexAttrib3f(index, x0, x1, x2);
     }
 }
 
 void
-WebGLContext::VertexAttrib4f(WebGLuint index, WebGLfloat x0, WebGLfloat x1,
-                             WebGLfloat x2, WebGLfloat x3)
+WebGLContext::VertexAttrib4f(GLuint index, GLfloat x0, GLfloat x1,
+                             GLfloat x2, GLfloat x3)
 {
-    if (!IsContextStable())
+    if (IsContextLost())
         return;
 
     MakeContextCurrent();
 
     if (index) {
         gl->fVertexAttrib4f(index, x0, x1, x2, x3);
     } else {
         mVertexAttrib0Vector[0] = x0;
@@ -98,78 +99,78 @@ WebGLContext::VertexAttrib4f(WebGLuint i
         mVertexAttrib0Vector[3] = x3;
         if (gl->IsGLES2())
             gl->fVertexAttrib4f(index, x0, x1, x2, x3);
     }
 }
 
 
 void
-WebGLContext::VertexAttrib1fv_base(WebGLuint idx, uint32_t arrayLength,
-                                   const WebGLfloat* ptr)
+WebGLContext::VertexAttrib1fv_base(GLuint idx, uint32_t arrayLength,
+                                   const GLfloat* ptr)
 {
     if (!ValidateAttribArraySetter("VertexAttrib1fv", 1, arrayLength))
         return;
 
     MakeContextCurrent();
     if (idx) {
         gl->fVertexAttrib1fv(idx, ptr);
     } else {
         mVertexAttrib0Vector[0] = ptr[0];
-        mVertexAttrib0Vector[1] = WebGLfloat(0);
-        mVertexAttrib0Vector[2] = WebGLfloat(0);
-        mVertexAttrib0Vector[3] = WebGLfloat(1);
+        mVertexAttrib0Vector[1] = GLfloat(0);
+        mVertexAttrib0Vector[2] = GLfloat(0);
+        mVertexAttrib0Vector[3] = GLfloat(1);
         if (gl->IsGLES2())
             gl->fVertexAttrib1fv(idx, ptr);
     }
 }
 
 void
-WebGLContext::VertexAttrib2fv_base(WebGLuint idx, uint32_t arrayLength,
-                                   const WebGLfloat* ptr)
+WebGLContext::VertexAttrib2fv_base(GLuint idx, uint32_t arrayLength,
+                                   const GLfloat* ptr)
 {
     if (!ValidateAttribArraySetter("VertexAttrib2fv", 2, arrayLength))
         return;
 
     MakeContextCurrent();
     if (idx) {
         gl->fVertexAttrib2fv(idx, ptr);
     } else {
         mVertexAttrib0Vector[0] = ptr[0];
         mVertexAttrib0Vector[1] = ptr[1];
-        mVertexAttrib0Vector[2] = WebGLfloat(0);
-        mVertexAttrib0Vector[3] = WebGLfloat(1);
+        mVertexAttrib0Vector[2] = GLfloat(0);
+        mVertexAttrib0Vector[3] = GLfloat(1);
         if (gl->IsGLES2())
             gl->fVertexAttrib2fv(idx, ptr);
     }
 }
 
 void
-WebGLContext::VertexAttrib3fv_base(WebGLuint idx, uint32_t arrayLength,
-                                   const WebGLfloat* ptr)
+WebGLContext::VertexAttrib3fv_base(GLuint idx, uint32_t arrayLength,
+                                   const GLfloat* ptr)
 {
     if (!ValidateAttribArraySetter("VertexAttrib3fv", 3, arrayLength))
         return;
 
     MakeContextCurrent();
     if (idx) {
         gl->fVertexAttrib3fv(idx, ptr);
     } else {
         mVertexAttrib0Vector[0] = ptr[0];
         mVertexAttrib0Vector[1] = ptr[1];
         mVertexAttrib0Vector[2] = ptr[2];
-        mVertexAttrib0Vector[3] = WebGLfloat(1);
+        mVertexAttrib0Vector[3] = GLfloat(1);
         if (gl->IsGLES2())
             gl->fVertexAttrib3fv(idx, ptr);
     }
 }
 
 void
-WebGLContext::VertexAttrib4fv_base(WebGLuint idx, uint32_t arrayLength,
-                                   const WebGLfloat* ptr)
+WebGLContext::VertexAttrib4fv_base(GLuint idx, uint32_t arrayLength,
+                                   const GLfloat* ptr)
 {
     if (!ValidateAttribArraySetter("VertexAttrib4fv", 4, arrayLength))
         return;
 
     MakeContextCurrent();
     if (idx) {
         gl->fVertexAttrib4fv(idx, ptr);
     } else {
@@ -178,55 +179,55 @@ WebGLContext::VertexAttrib4fv_base(WebGL
         mVertexAttrib0Vector[2] = ptr[2];
         mVertexAttrib0Vector[3] = ptr[3];
         if (gl->IsGLES2())
             gl->fVertexAttrib4fv(idx, ptr);
     }
 }
 
 void
-WebGLContext::EnableVertexAttribArray(WebGLuint index)
+WebGLContext::EnableVertexAttribArray(GLuint index)
 {
-    if (!IsContextStable())
+    if (IsContextLost())
         return;
 
     if (!ValidateAttribIndex(index, "enableVertexAttribArray"))
         return;
 
     MakeContextCurrent();
     InvalidateBufferFetching();
 
     gl->fEnableVertexAttribArray(index);
     mBoundVertexArray->mAttribBuffers[index].enabled = true;
 }
 
 void
-WebGLContext::DisableVertexAttribArray(WebGLuint index)
+WebGLContext::DisableVertexAttribArray(GLuint index)
 {
-    if (!IsContextStable())
+    if (IsContextLost())
         return;
 
     if (!ValidateAttribIndex(index, "disableVertexAttribArray"))
         return;
 
     MakeContextCurrent();
     InvalidateBufferFetching();
 
     if (index || gl->IsGLES2())
         gl->fDisableVertexAttribArray(index);
 
     mBoundVertexArray->mAttribBuffers[index].enabled = false;
 }
 
 
 JS::Value
-WebGLContext::GetVertexAttrib(JSContext* cx, WebGLuint index, WebGLenum pname,
+WebGLContext::GetVertexAttrib(JSContext* cx, GLuint index, GLenum pname,
                               ErrorResult& rv)
 {
-    if (!IsContextStable())
+    if (IsContextLost())
         return JS::NullValue();
 
     if (!mBoundVertexArray->EnsureAttribIndex(index, "getVertexAttrib"))
         return JS::NullValue();
 
     MakeContextCurrent();
 
     switch (pname) {
@@ -266,17 +267,17 @@ WebGLContext::GetVertexAttrib(JSContext*
             {
                 return JS::Int32Value(mBoundVertexArray->mAttribBuffers[index].divisor);
             }
             break;
         }
 
         case LOCAL_GL_CURRENT_VERTEX_ATTRIB:
         {
-            WebGLfloat vec[4] = {0, 0, 0, 1};
+            GLfloat vec[4] = {0, 0, 0, 1};
             if (index) {
                 gl->fGetVertexAttribfv(index, LOCAL_GL_CURRENT_VERTEX_ATTRIB, &vec[0]);
             } else {
                 vec[0] = mVertexAttrib0Vector[0];
                 vec[1] = mVertexAttrib0Vector[1];
                 vec[2] = mVertexAttrib0Vector[2];
                 vec[3] = mVertexAttrib0Vector[3];
             }
@@ -302,44 +303,44 @@ WebGLContext::GetVertexAttrib(JSContext*
     }
 
     ErrorInvalidEnumInfo("getVertexAttrib: parameter", pname);
 
     return JS::NullValue();
 }
 
 WebGLsizeiptr
-WebGLContext::GetVertexAttribOffset(WebGLuint index, WebGLenum pname)
+WebGLContext::GetVertexAttribOffset(GLuint index, GLenum pname)
 {
-    if (!IsContextStable())
+    if (IsContextLost())
         return 0;
 
     if (!ValidateAttribIndex(index, "getVertexAttribOffset"))
         return 0;
 
     if (pname != LOCAL_GL_VERTEX_ATTRIB_ARRAY_POINTER) {
         ErrorInvalidEnum("getVertexAttribOffset: bad parameter");
         return 0;
     }
 
     return mBoundVertexArray->mAttribBuffers[index].byteOffset;
 }
 
 void
-WebGLContext::VertexAttribPointer(WebGLuint index, WebGLint size, WebGLenum type,
-                                  WebGLboolean normalized, WebGLsizei stride,
+WebGLContext::VertexAttribPointer(GLuint index, GLint size, GLenum type,
+                                  WebGLboolean normalized, GLsizei stride,
                                   WebGLintptr byteOffset)
 {
-    if (!IsContextStable())
+    if (IsContextLost())
         return;
 
     if (mBoundArrayBuffer == nullptr)
         return ErrorInvalidOperation("vertexAttribPointer: must have valid GL_ARRAY_BUFFER binding");
 
-    WebGLsizei requiredAlignment = 1;
+    GLsizei requiredAlignment = 1;
     switch (type) {
         case LOCAL_GL_BYTE:
         case LOCAL_GL_UNSIGNED_BYTE:
             requiredAlignment = 1;
             break;
         case LOCAL_GL_SHORT:
         case LOCAL_GL_UNSIGNED_SHORT:
             requiredAlignment = 2;
@@ -348,17 +349,17 @@ WebGLContext::VertexAttribPointer(WebGLu
         case LOCAL_GL_FLOAT:
             requiredAlignment = 4;
             break;
         default:
             return ErrorInvalidEnumInfo("vertexAttribPointer: type", type);
     }
 
     // requiredAlignment should always be a power of two.
-    WebGLsizei requiredAlignmentMask = requiredAlignment - 1;
+    GLsizei requiredAlignmentMask = requiredAlignment - 1;
 
     if ( !mBoundVertexArray->EnsureAttribIndex(index, "vertexAttribPointer") ) {
         return;
     }
 
     if (size < 1 || size > 4)
         return ErrorInvalidValue("vertexAttribPointer: invalid element size");
 
@@ -398,36 +399,36 @@ WebGLContext::VertexAttribPointer(WebGLu
     MakeContextCurrent();
 
     gl->fVertexAttribPointer(index, size, type, normalized,
                              stride,
                              reinterpret_cast<void*>(byteOffset));
 }
 
 void
-WebGLContext::VertexAttribDivisor(WebGLuint index, WebGLuint divisor)
+WebGLContext::VertexAttribDivisor(GLuint index, GLuint divisor)
 {
-    if (!IsContextStable())
+    if (IsContextLost())
         return;
 
     if ( !mBoundVertexArray->EnsureAttribIndex(index, "vertexAttribDivisor") ) {
         return;
     }
 
     WebGLVertexAttribData& vd = mBoundVertexArray->mAttribBuffers[index];
     vd.divisor = divisor;
 
     InvalidateBufferFetching();
 
     MakeContextCurrent();
 
     gl->fVertexAttribDivisor(index, divisor);
 }
 
-bool WebGLContext::DrawArrays_check(WebGLint first, WebGLsizei count, WebGLsizei primcount, const char* info)
+bool WebGLContext::DrawArrays_check(GLint first, GLsizei count, GLsizei primcount, const char* info)
 {
     if (first < 0 || count < 0) {
         ErrorInvalidValue("%s: negative first or count", info);
         return false;
     }
 
     if (primcount < 0) {
         ErrorInvalidValue("%s: negative primcount", info);
@@ -493,53 +494,53 @@ bool WebGLContext::DrawArrays_check(WebG
         return false;
     }
     BindFakeBlackTextures();
 
     return true;
 }
 
 void
-WebGLContext::DrawArrays(GLenum mode, WebGLint first, WebGLsizei count)
+WebGLContext::DrawArrays(GLenum mode, GLint first, GLsizei count)
 {
-    if (!IsContextStable())
+    if (IsContextLost())
         return;
 
     if (!ValidateDrawModeEnum(mode, "drawArrays: mode"))
         return;
 
     if (!DrawArrays_check(first, count, 1, "drawArrays"))
         return;
 
     SetupContextLossTimer();
     gl->fDrawArrays(mode, first, count);
 
     Draw_cleanup();
 }
 
 void
-WebGLContext::DrawArraysInstanced(GLenum mode, WebGLint first, WebGLsizei count, WebGLsizei primcount)
+WebGLContext::DrawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei primcount)
 {
-    if (!IsContextStable())
+    if (IsContextLost())
         return;
 
     if (!ValidateDrawModeEnum(mode, "drawArraysInstanced: mode"))
         return;
 
     if (!DrawArrays_check(first, count, primcount, "drawArraysInstanced"))
         return;
 
     SetupContextLossTimer();
     gl->fDrawArraysInstanced(mode, first, count, primcount);
 
     Draw_cleanup();
 }
 
 bool
-WebGLContext::DrawElements_check(WebGLsizei count, WebGLenum type, WebGLintptr byteOffset, WebGLsizei primcount, const char* info)
+WebGLContext::DrawElements_check(GLsizei count, GLenum type, WebGLintptr byteOffset, GLsizei primcount, const char* info)
 {
     if (count < 0 || byteOffset < 0) {
         ErrorInvalidValue("%s: negative count or offset", info);
         return false;
     }
 
     if (primcount < 0) {
         ErrorInvalidValue("%s: negative primcount", info);
@@ -552,17 +553,17 @@ WebGLContext::DrawElements_check(WebGLsi
 
     // If count is 0, there's nothing to do.
     if (count == 0 || primcount == 0) {
         return false;
     }
 
     CheckedUint32 checked_byteCount;
 
-    WebGLsizei first = 0;
+    GLsizei first = 0;
 
     if (type == LOCAL_GL_UNSIGNED_SHORT) {
         checked_byteCount = 2 * CheckedUint32(count);
         if (byteOffset % 2 != 0) {
             ErrorInvalidOperation("%s: invalid byteOffset for UNSIGNED_SHORT (must be a multiple of 2)", info);
             return false;
         }
         first = byteOffset / 2;
@@ -657,39 +658,39 @@ WebGLContext::DrawElements_check(WebGLsi
         return false;
     }
     BindFakeBlackTextures();
 
     return true;
 }
 
 void
-WebGLContext::DrawElements(WebGLenum mode, WebGLsizei count, WebGLenum type,
+WebGLContext::DrawElements(GLenum mode, GLsizei count, GLenum type,
                                WebGLintptr byteOffset)
 {
-    if (!IsContextStable())
+    if (IsContextLost())
         return;
 
     if (!ValidateDrawModeEnum(mode, "drawElements: mode"))
         return;
 
     if (!DrawElements_check(count, type, byteOffset, 1, "drawElements"))
         return;
 
     SetupContextLossTimer();
     gl->fDrawElements(mode, count, type, reinterpret_cast<GLvoid*>(byteOffset));
 
     Draw_cleanup();
 }
 
 void
-WebGLContext::DrawElementsInstanced(WebGLenum mode, WebGLsizei count, WebGLenum type,
-                                        WebGLintptr byteOffset, WebGLsizei primcount)
+WebGLContext::DrawElementsInstanced(GLenum mode, GLsizei count, GLenum type,
+                                        WebGLintptr byteOffset, GLsizei primcount)
 {
-    if (!IsContextStable())
+    if (IsContextLost())
         return;
 
     if (!ValidateDrawModeEnum(mode, "drawElementsInstanced: mode"))
         return;
 
     if (!DrawElements_check(count, type, byteOffset, primcount, "drawElementsInstanced"))
         return;
 
--- a/content/canvas/src/WebGLExtensionBase.cpp
+++ b/content/canvas/src/WebGLExtensionBase.cpp
@@ -15,15 +15,10 @@ WebGLExtensionBase::WebGLExtensionBase(W
 }
 
 WebGLExtensionBase::~WebGLExtensionBase()
 {
 }
 
 NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_0(WebGLExtensionBase)
 
-NS_IMPL_CYCLE_COLLECTING_ADDREF(WebGLExtensionBase)
-NS_IMPL_CYCLE_COLLECTING_RELEASE(WebGLExtensionBase)
-
-NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(WebGLExtensionBase)
-  NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
-  NS_INTERFACE_MAP_ENTRY(nsISupports)
-NS_INTERFACE_MAP_END
+NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(WebGLExtensionBase, AddRef)
+NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(WebGLExtensionBase, Release)
--- a/content/canvas/src/WebGLExtensionDrawBuffers.cpp
+++ b/content/canvas/src/WebGLExtensionDrawBuffers.cpp
@@ -3,16 +3,17 @@
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "WebGLContext.h"
 #include "WebGLExtensions.h"
 #include "mozilla/dom/WebGLRenderingContextBinding.h"
 #include "WebGLTexture.h"
 #include "WebGLRenderbuffer.h"
 #include "WebGLFramebuffer.h"
+#include "GLContext.h"
 
 #include <algorithm>
 
 using namespace mozilla;
 using namespace gl;
 
 WebGLExtensionDrawBuffers::WebGLExtensionDrawBuffers(WebGLContext* context)
     : WebGLExtensionBase(context)
--- a/content/canvas/src/WebGLExtensionInstancedArrays.cpp
+++ b/content/canvas/src/WebGLExtensionInstancedArrays.cpp
@@ -1,47 +1,48 @@
 /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
 /* 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/. */
 
 #include "WebGLContext.h"
 #include "WebGLExtensions.h"
 #include "mozilla/dom/WebGLRenderingContextBinding.h"
+#include "GLContext.h"
 
 using namespace mozilla;
 
 WebGLExtensionInstancedArrays::WebGLExtensionInstancedArrays(WebGLContext* context)
   : WebGLExtensionBase(context)
 {
     MOZ_ASSERT(IsSupported(context), "should not construct WebGLExtensionInstancedArrays: "
                                      "ANGLE_instanced_arrays unsupported.");
 }
 
 WebGLExtensionInstancedArrays::~WebGLExtensionInstancedArrays()
 {
 }
 
 void
-WebGLExtensionInstancedArrays::DrawArraysInstancedANGLE(WebGLenum mode, WebGLint first,
-                                                        WebGLsizei count, WebGLsizei primcount)
+WebGLExtensionInstancedArrays::DrawArraysInstancedANGLE(GLenum mode, GLint first,
+                                                        GLsizei count, GLsizei primcount)
 {
     mContext->DrawArraysInstanced(mode, first, count, primcount);
 }
 
 void
-WebGLExtensionInstancedArrays::DrawElementsInstancedANGLE(WebGLenum mode, WebGLsizei count,
-                                                          WebGLenum type, WebGLintptr offset,
-                                                          WebGLsizei primcount)
+WebGLExtensionInstancedArrays::DrawElementsInstancedANGLE(GLenum mode, GLsizei count,
+                                                          GLenum type, WebGLintptr offset,
+                                                          GLsizei primcount)
 {
     mContext->DrawElementsInstanced(mode, count, type, offset, primcount);
 }
 
 void
-WebGLExtensionInstancedArrays::VertexAttribDivisorANGLE(WebGLuint index, WebGLuint divisor)
+WebGLExtensionInstancedArrays::VertexAttribDivisorANGLE(GLuint index, GLuint divisor)
 {
     mContext->VertexAttribDivisor(index, divisor);
 }
 
 bool
 WebGLExtensionInstancedArrays::IsSupported(const WebGLContext* context)
 {
     gl::GLContext* gl = context->GL();
--- a/content/canvas/src/WebGLExtensionVertexArray.cpp
+++ b/content/canvas/src/WebGLExtensionVertexArray.cpp
@@ -3,16 +3,17 @@
  * 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/. */
 
 #include "WebGLContext.h"
 #include "WebGLBuffer.h"
 #include "WebGLVertexArray.h"
 #include "WebGLExtensions.h"
 #include "mozilla/dom/WebGLRenderingContextBinding.h"
+#include "GLContext.h"
 
 using namespace mozilla;
 
 WebGLExtensionVertexArray::WebGLExtensionVertexArray(WebGLContext* context)
   : WebGLExtensionBase(context)
 {
     MOZ_ASSERT(IsSupported(context), "should not construct WebGLExtensionVertexArray :"
                                      "OES_vertex_array_object unsuported.");
--- a/content/canvas/src/WebGLExtensions.h
+++ b/content/canvas/src/WebGLExtensions.h
@@ -6,30 +6,29 @@
 #ifndef WEBGLEXTENSIONS_H_
 #define WEBGLEXTENSIONS_H_
 
 namespace mozilla {
 
 class WebGLContext;
 
 class WebGLExtensionBase
-    : public nsISupports
+    : public nsWrapperCache
     , public WebGLContextBoundObject
-    , public nsWrapperCache
 {
 public:
     WebGLExtensionBase(WebGLContext*);
     virtual ~WebGLExtensionBase();
 
     WebGLContext *GetParentObject() const {
         return Context();
     }
 
-    NS_DECL_CYCLE_COLLECTING_ISUPPORTS
-    NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(WebGLExtensionBase)
+    NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(WebGLExtensionBase)
+    NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(WebGLExtensionBase)
 };
 
 #define DECL_WEBGL_EXTENSION_GOOP                                           \
     virtual JSObject* WrapObject(JSContext *cx,                             \
                                  JS::Handle<JSObject*> scope) MOZ_OVERRIDE;
 
 #define IMPL_WEBGL_EXTENSION_GOOP(WebGLExtensionType) \
     JSObject* \
@@ -191,22 +190,22 @@ public:
 
 class WebGLExtensionInstancedArrays
     : public WebGLExtensionBase
 {
 public:
     WebGLExtensionInstancedArrays(WebGLContext* context);
     virtual ~WebGLExtensionInstancedArrays();
 
-    void DrawArraysInstancedANGLE(WebGLenum mode, WebGLint first,
-                                  WebGLsizei count, WebGLsizei primcount);
-    void DrawElementsInstancedANGLE(WebGLenum mode, WebGLsizei count,
-                                    WebGLenum type, WebGLintptr offset,
-                                    WebGLsizei primcount);
-    void VertexAttribDivisorANGLE(WebGLuint index, WebGLuint divisor);
+    void DrawArraysInstancedANGLE(GLenum mode, GLint first,
+                                  GLsizei count, GLsizei primcount);
+    void DrawElementsInstancedANGLE(GLenum mode, GLsizei count,
+                                    GLenum type, WebGLintptr offset,
+                                    GLsizei primcount);
+    void VertexAttribDivisorANGLE(GLuint index, GLuint divisor);
 
     static bool IsSupported(const WebGLContext* context);
 
     DECL_WEBGL_EXTENSION_GOOP
 };
 
 } // namespace mozilla
 
--- a/content/canvas/src/WebGLFramebuffer.cpp
+++ b/content/canvas/src/WebGLFramebuffer.cpp
@@ -6,16 +6,17 @@
 #include "WebGLContext.h"
 #include "WebGLFramebuffer.h"
 #include "WebGLExtensions.h"
 #include "WebGLRenderbuffer.h"
 #include "WebGLTexture.h"
 #include "mozilla/dom/WebGLRenderingContextBinding.h"
 #include "WebGLTexture.h"
 #include "WebGLRenderbuffer.h"
+#include "GLContext.h"
 
 using namespace mozilla;
 
 JSObject*
 WebGLFramebuffer::WrapObject(JSContext *cx, JS::Handle<JSObject*> scope) {
     return dom::WebGLFramebufferBinding::Wrap(cx, scope, this);
 }
 
@@ -39,30 +40,30 @@ bool
 WebGLFramebuffer::Attachment::IsDeleteRequested() const {
     return Texture() ? Texture()->IsDeleteRequested()
          : Renderbuffer() ? Renderbuffer()->IsDeleteRequested()
          : false;
 }
 
 bool
 WebGLFramebuffer::Attachment::HasAlpha() const {
-    WebGLenum format = 0;
+    GLenum format = 0;
     if (Texture() && Texture()->HasImageInfoAt(mTextureLevel, mTextureCubeMapFace))
         format = Texture()->ImageInfoAt(mTextureLevel, mTextureCubeMapFace).Format();
     else if (Renderbuffer())
         format = Renderbuffer()->InternalFormat();
     return format == LOCAL_GL_RGBA ||
            format == LOCAL_GL_LUMINANCE_ALPHA ||
            format == LOCAL_GL_ALPHA ||
            format == LOCAL_GL_RGBA4 ||
            format == LOCAL_GL_RGB5_A1;
 }
 
 void
-WebGLFramebuffer::Attachment::SetTexture(WebGLTexture *tex, WebGLint level, WebGLenum face) {
+WebGLFramebuffer::Attachment::SetTexture(WebGLTexture *tex, GLint level, GLenum face) {
     mTexturePtr = tex;
     mRenderbufferPtr = nullptr;
     mTextureLevel = level;
     mTextureCubeMapFace = face;
 }
 
 bool
 WebGLFramebuffer::Attachment::HasUninitializedRenderbuffer() const {
@@ -96,49 +97,49 @@ WebGLFramebuffer::Attachment::IsComplete
         !thisRect->Width() ||
         !thisRect->Height())
         return false;
 
     if (mTexturePtr) {
         if (!mTexturePtr->HasImageInfoAt(0, 0))
             return false;
 
-        WebGLenum format = mTexturePtr->ImageInfoAt(0).Format();
+        GLenum format = mTexturePtr->ImageInfoAt(0).Format();
 
         if (mAttachmentPoint == LOCAL_GL_DEPTH_ATTACHMENT) {
             return format == LOCAL_GL_DEPTH_COMPONENT;
         }
         else if (mAttachmentPoint == LOCAL_GL_DEPTH_STENCIL_ATTACHMENT) {
             return format == LOCAL_GL_DEPTH_STENCIL;
         }
         else if (mAttachmentPoint >= LOCAL_GL_COLOR_ATTACHMENT0 &&
-                 mAttachmentPoint < WebGLenum(LOCAL_GL_COLOR_ATTACHMENT0 + WebGLContext::sMaxColorAttachments)) {
+                 mAttachmentPoint < GLenum(LOCAL_GL_COLOR_ATTACHMENT0 + WebGLContext::sMaxColorAttachments)) {
             return (format == LOCAL_GL_ALPHA ||
                     format == LOCAL_GL_LUMINANCE ||
                     format == LOCAL_GL_LUMINANCE_ALPHA ||
                     format == LOCAL_GL_RGB ||
                     format == LOCAL_GL_RGBA);
         }
         MOZ_CRASH("Invalid WebGL attachment poin?");
     }
 
     if (mRenderbufferPtr) {
-        WebGLenum format = mRenderbufferPtr->InternalFormat();
+        GLenum format = mRenderbufferPtr->InternalFormat();
 
         if (mAttachmentPoint == LOCAL_GL_DEPTH_ATTACHMENT) {
             return format == LOCAL_GL_DEPTH_COMPONENT16;
         }
         else if (mAttachmentPoint == LOCAL_GL_STENCIL_ATTACHMENT) {
             return format == LOCAL_GL_STENCIL_INDEX8;
         }
         else if (mAttachmentPoint == LOCAL_GL_DEPTH_STENCIL_ATTACHMENT) {
             return format == LOCAL_GL_DEPTH_STENCIL;
         }
         else if (mAttachmentPoint >= LOCAL_GL_COLOR_ATTACHMENT0 &&
-                 mAttachmentPoint < WebGLenum(LOCAL_GL_COLOR_ATTACHMENT0 + WebGLContext::sMaxColorAttachments)) {
+                 mAttachmentPoint < GLenum(LOCAL_GL_COLOR_ATTACHMENT0 + WebGLContext::sMaxColorAttachments)) {
             return (format == LOCAL_GL_RGB565 ||
                     format == LOCAL_GL_RGB5_A1 ||
                     format == LOCAL_GL_RGBA4);
         }
         MOZ_CRASH("Invalid WebGL attachment poin?");
     }
 
     NS_ABORT(); // should never get there
@@ -152,19 +153,19 @@ WebGLFramebuffer::Delete() {
     mStencilAttachment.Reset();
     mDepthStencilAttachment.Reset();
     mContext->MakeContextCurrent();
     mContext->gl->fDeleteFramebuffers(1, &mGLName);
     LinkedListElement<WebGLFramebuffer>::removeFrom(mContext->mFramebuffers);
 }
 
 void
-WebGLFramebuffer::FramebufferRenderbuffer(WebGLenum target,
-                             WebGLenum attachment,
-                             WebGLenum rbtarget,
+WebGLFramebuffer::FramebufferRenderbuffer(GLenum target,
+                             GLenum attachment,
+                             GLenum rbtarget,
                              WebGLRenderbuffer *wrb)
 {
     MOZ_ASSERT(mContext->mBoundFramebuffer == this);
     if (!mContext->ValidateObjectAllowNull("framebufferRenderbuffer: renderbuffer", wrb))
     {
         return;
     }
 
@@ -192,41 +193,41 @@ WebGLFramebuffer::FramebufferRenderbuffe
 
         size_t colorAttachmentId = size_t(attachment - LOCAL_GL_COLOR_ATTACHMENT0);
         EnsureColorAttachments(colorAttachmentId);
         mColorAttachments[colorAttachmentId].SetRenderbuffer(wrb);
         break;
     }
 
     mContext->MakeContextCurrent();
-    WebGLuint parambuffername = wrb ? wrb->GLName() : 0;
+    GLuint parambuffername = wrb ? wrb->GLName() : 0;
     if (attachment == LOCAL_GL_DEPTH_STENCIL_ATTACHMENT) {
-        WebGLuint depthbuffername = parambuffername;
-        WebGLuint stencilbuffername = parambuffername;
+        GLuint depthbuffername = parambuffername;
+        GLuint stencilbuffername = parambuffername;
         if (!parambuffername){
             depthbuffername   = mDepthAttachment.Renderbuffer()   ? mDepthAttachment.Renderbuffer()->GLName()   : 0;
             stencilbuffername = mStencilAttachment.Renderbuffer() ? mStencilAttachment.Renderbuffer()->GLName() : 0;
         }
         mContext->gl->fFramebufferRenderbuffer(target, LOCAL_GL_DEPTH_ATTACHMENT, rbtarget, depthbuffername);
         mContext->gl->fFramebufferRenderbuffer(target, LOCAL_GL_STENCIL_ATTACHMENT, rbtarget, stencilbuffername);
     } else {
-        WebGLuint renderbuffername = parambuffername;
+        GLuint renderbuffername = parambuffername;
         if(!parambuffername && (attachment == LOCAL_GL_DEPTH_ATTACHMENT || attachment == LOCAL_GL_STENCIL_ATTACHMENT)){
             renderbuffername = mDepthStencilAttachment.Renderbuffer() ? mDepthStencilAttachment.Renderbuffer()->GLName() : 0;
         }
         mContext->gl->fFramebufferRenderbuffer(target, attachment, rbtarget, renderbuffername);
     }
 }
 
 void
-WebGLFramebuffer::FramebufferTexture2D(WebGLenum target,
-                          WebGLenum attachment,
-                          WebGLenum textarget,
+WebGLFramebuffer::FramebufferTexture2D(GLenum target,
+                          GLenum attachment,
+                          GLenum textarget,
                           WebGLTexture *wtex,
-                          WebGLint level)
+                          GLint level)
 {
     MOZ_ASSERT(mContext->mBoundFramebuffer == this);
     if (!mContext->ValidateObjectAllowNull("framebufferTexture2D: texture",
                                            wtex))
     {
         return;
     }
 
@@ -259,28 +260,28 @@ WebGLFramebuffer::FramebufferTexture2D(W
 
         size_t colorAttachmentId = size_t(attachment - LOCAL_GL_COLOR_ATTACHMENT0);
         EnsureColorAttachments(colorAttachmentId);
         mColorAttachments[colorAttachmentId].SetTexture(wtex, level, face);
         break;
     }
 
     mContext->MakeContextCurrent();
-    WebGLuint paramtexturename = wtex ? wtex->GLName() : 0;
+    GLuint paramtexturename = wtex ? wtex->GLName() : 0;
     if (attachment == LOCAL_GL_DEPTH_STENCIL_ATTACHMENT) {
-        WebGLuint depthtexturename = paramtexturename;
-        WebGLuint stenciltexturename = paramtexturename;
+        GLuint depthtexturename = paramtexturename;
+        GLuint stenciltexturename = paramtexturename;
         if(!paramtexturename){
             depthtexturename   = mDepthAttachment.Texture()   ? mDepthAttachment.Texture()->GLName()   : 0;
             stenciltexturename = mStencilAttachment.Texture() ? mStencilAttachment.Texture()->GLName() : 0;
         }
         mContext->gl->fFramebufferTexture2D(target, LOCAL_GL_DEPTH_ATTACHMENT, textarget, depthtexturename, level);
         mContext->gl->fFramebufferTexture2D(target, LOCAL_GL_STENCIL_ATTACHMENT, textarget, stenciltexturename, level);
     } else {
-        WebGLuint texturename = paramtexturename;
+        GLuint texturename = paramtexturename;
         if(!paramtexturename && (attachment == LOCAL_GL_DEPTH_ATTACHMENT || attachment == LOCAL_GL_STENCIL_ATTACHMENT)){
             texturename = mDepthStencilAttachment.Texture() ? mDepthStencilAttachment.Texture()->GLName() : 0;
         }
         mContext->gl->fFramebufferTexture2D(target, attachment, textarget, texturename, level);
     }
 
     return;
 }
@@ -315,17 +316,17 @@ WebGLFramebuffer::HasAttachmentsOfMismat
     }
 
     return ((mDepthAttachment.IsDefined() && !mDepthAttachment.HasSameDimensionsAs(mColorAttachments[0])) ||
             (mStencilAttachment.IsDefined() && !mStencilAttachment.HasSameDimensionsAs(mColorAttachments[0])) ||
             (mDepthStencilAttachment.IsDefined() && !mDepthStencilAttachment.HasSameDimensionsAs(mColorAttachments[0])));
 }
 
 const WebGLFramebuffer::Attachment&
-WebGLFramebuffer::GetAttachment(WebGLenum attachment) const {
+WebGLFramebuffer::GetAttachment(GLenum attachment) const {
     if (attachment == LOCAL_GL_DEPTH_STENCIL_ATTACHMENT)
         return mDepthStencilAttachment;
     if (attachment == LOCAL_GL_DEPTH_ATTACHMENT)
         return mDepthAttachment;
     if (attachment == LOCAL_GL_STENCIL_ATTACHMENT)
         return mStencilAttachment;
 
     if (!CheckColorAttachementNumber(attachment, "getAttachment")) {
@@ -415,17 +416,17 @@ WebGLFramebuffer::CheckAndInitializeRend
     const WebGLRectangleObject *rect = mColorAttachments[0].RectangleObject();
     if (!rect ||
         !rect->Width() ||
         !rect->Height())
         return false;
 
     mContext->MakeContextCurrent();
 
-    WebGLenum status = mContext->CheckFramebufferStatus(LOCAL_GL_FRAMEBUFFER);
+    GLenum status = mContext->CheckFramebufferStatus(LOCAL_GL_FRAMEBUFFER);
     if (status != LOCAL_GL_FRAMEBUFFER_COMPLETE)
         return false;
 
     uint32_t mask = 0;
     bool colorAttachmentsMask[WebGLContext::sMaxColorAttachments] = { false };
 
     MOZ_ASSERT( colorAttachmentCount <= WebGLContext::sMaxColorAttachments );
 
@@ -466,24 +467,24 @@ WebGLFramebuffer::CheckAndInitializeRend
         mStencilAttachment.Renderbuffer()->SetInitialized(true);
 
     if (mDepthStencilAttachment.HasUninitializedRenderbuffer())
         mDepthStencilAttachment.Renderbuffer()->SetInitialized(true);
 
     return true;
 }
 
-bool WebGLFramebuffer::CheckColorAttachementNumber(WebGLenum attachment, const char * functionName) const
+bool WebGLFramebuffer::CheckColorAttachementNumber(GLenum attachment, const char * functionName) const
 {
     const char* const errorFormating = "%s: attachment: invalid enum value 0x%x";
 
     if (mContext->IsExtensionEnabled(WebGLContext::WEBGL_draw_buffers))
     {
         if (attachment < LOCAL_GL_COLOR_ATTACHMENT0 ||
-            attachment > WebGLenum(LOCAL_GL_COLOR_ATTACHMENT0 + mContext->mGLMaxColorAttachments))
+            attachment > GLenum(LOCAL_GL_COLOR_ATTACHMENT0 + mContext->mGLMaxColorAttachments))
         {
             mContext->ErrorInvalidEnum(errorFormating, functionName, attachment);
             return false;
         }
     }
     else if (attachment != LOCAL_GL_COLOR_ATTACHMENT0)
     {
         if (attachment > LOCAL_GL_COLOR_ATTACHMENT0 &&
--- a/content/canvas/src/WebGLFramebuffer.h
+++ b/content/canvas/src/WebGLFramebuffer.h
@@ -30,53 +30,53 @@ public:
         DeleteOnce();
     }
 
     struct Attachment
     {
         // deleting a texture or renderbuffer immediately detaches it
         WebGLRefPtr<WebGLTexture> mTexturePtr;
         WebGLRefPtr<WebGLRenderbuffer> mRenderbufferPtr;
-        WebGLenum mAttachmentPoint;
-        WebGLint mTextureLevel;
-        WebGLenum mTextureCubeMapFace;
+        GLenum mAttachmentPoint;
+        GLint mTextureLevel;
+        GLenum mTextureCubeMapFace;
 
-        Attachment(WebGLenum aAttachmentPoint = LOCAL_GL_COLOR_ATTACHMENT0)
+        Attachment(GLenum aAttachmentPoint = LOCAL_GL_COLOR_ATTACHMENT0)
             : mAttachmentPoint(aAttachmentPoint)
         {}
 
         bool IsDefined() const {
             return Texture() || Renderbuffer();
         }
 
         bool IsDeleteRequested() const;
 
         bool HasAlpha() const;
 
-        void SetTexture(WebGLTexture *tex, WebGLint level, WebGLenum face);
+        void SetTexture(WebGLTexture *tex, GLint level, GLenum face);
         void SetRenderbuffer(WebGLRenderbuffer *rb) {
             mTexturePtr = nullptr;
             mRenderbufferPtr = rb;
         }
         const WebGLTexture *Texture() const {
             return mTexturePtr;
         }
         WebGLTexture *Texture() {
             return mTexturePtr;
         }
         const WebGLRenderbuffer *Renderbuffer() const {
             return mRenderbufferPtr;
         }
         WebGLRenderbuffer *Renderbuffer() {
             return mRenderbufferPtr;
         }
-        WebGLint TextureLevel() const {
+        GLint TextureLevel() const {
             return mTextureLevel;
         }
-        WebGLenum TextureCubeMapFace() const {
+        GLenum TextureCubeMapFace() const {
             return mTextureCubeMapFace;
         }
 
         bool HasUninitializedRenderbuffer() const;
 
         void Reset() {
             mTexturePtr = nullptr;
             mRenderbufferPtr = nullptr;
@@ -87,28 +87,28 @@ public:
 
         bool IsComplete() const;
     };
 
     void Delete();
 
     bool HasEverBeenBound() { return mHasEverBeenBound; }
     void SetHasEverBeenBound(bool x) { mHasEverBeenBound = x; }
-    WebGLuint GLName() { return mGLName; }
+    GLuint GLName() { return mGLName; }
 
-    void FramebufferRenderbuffer(WebGLenum target,
-                                 WebGLenum attachment,
-                                 WebGLenum rbtarget,
+    void FramebufferRenderbuffer(GLenum target,
+                                 GLenum attachment,
+                                 GLenum rbtarget,
                                  WebGLRenderbuffer *wrb);
 
-    void FramebufferTexture2D(WebGLenum target,
-                              WebGLenum attachment,
-                              WebGLenum textarget,
+    void FramebufferTexture2D(GLenum target,
+                              GLenum attachment,
+                              GLenum textarget,
                               WebGLTexture *wtex,
-                              WebGLint level);
+                              GLint level);
 
     bool HasIncompleteAttachment() const;
 
     bool HasDepthStencilConflict() const {
         return int(mDepthAttachment.IsDefined()) +
                int(mStencilAttachment.IsDefined()) +
                int(mDepthStencilAttachment.IsDefined()) >= 2;
     }
@@ -126,17 +126,17 @@ public:
     const Attachment& StencilAttachment() const {
         return mStencilAttachment;
     }
 
     const Attachment& DepthStencilAttachment() const {
         return mDepthStencilAttachment;
     }
 
-    const Attachment& GetAttachment(WebGLenum attachment) const;
+    const Attachment& GetAttachment(GLenum attachment) const;
 
     void DetachTexture(const WebGLTexture *tex);
 
     void DetachRenderbuffer(const WebGLRenderbuffer *rb);
 
     const WebGLRectangleObject *RectangleObject() {
         return mColorAttachments[0].RectangleObject();
     }
@@ -148,19 +148,19 @@ public:
     virtual JSObject* WrapObject(JSContext *cx,
                                  JS::Handle<JSObject*> scope) MOZ_OVERRIDE;
 
     NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(WebGLFramebuffer)
     NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(WebGLFramebuffer)
 
     bool CheckAndInitializeRenderbuffers();
 
-    bool CheckColorAttachementNumber(WebGLenum attachment, const char * functionName) const;
+    bool CheckColorAttachementNumber(GLenum attachment, const char * functionName) const;
 
-    WebGLuint mGLName;
+    GLuint mGLName;
     bool mHasEverBeenBound;
 
     void EnsureColorAttachments(size_t colorAttachmentId);
 
     // we only store pointers to attached renderbuffers, not to attached textures, because
     // we will only need to initialize renderbuffers. Textures are already initialized.
     nsTArray<Attachment> mColorAttachments;
     Attachment mDepthAttachment,
--- a/content/canvas/src/WebGLObjectModel.h
+++ b/content/canvas/src/WebGLObjectModel.h
@@ -275,26 +275,26 @@ protected:
 // this class is a mixin for GL objects that have dimensions
 // that we need to track.
 class WebGLRectangleObject
 {
 public:
     WebGLRectangleObject()
         : mWidth(0), mHeight(0) { }
 
-    WebGLRectangleObject(WebGLsizei width, WebGLsizei height)
+    WebGLRectangleObject(GLsizei width, GLsizei height)
         : mWidth(width), mHeight(height) { }
 
-    WebGLsizei Width() const { return mWidth; }
-    void width(WebGLsizei value) { mWidth = value; }
+    GLsizei Width() const { return mWidth; }
+    void width(GLsizei value) { mWidth = value; }
 
-    WebGLsizei Height() const { return mHeight; }
-    void height(WebGLsizei value) { mHeight = value; }
+    GLsizei Height() const { return mHeight; }
+    void height(GLsizei value) { mHeight = value; }
 
-    void setDimensions(WebGLsizei width, WebGLsizei height) {
+    void setDimensions(GLsizei width, GLsizei height) {
         mWidth = width;
         mHeight = height;
     }
 
     void setDimensions(WebGLRectangleObject *rect) {
         if (rect) {
             mWidth = rect->Width();
             mHeight = rect->Height();
@@ -304,18 +304,18 @@ public:
         }
     }
 
     bool HasSameDimensionsAs(const WebGLRectangleObject& other) const {
         return Width() == other.Width() && Height() == other.Height(); 
     }
 
 protected:
-    WebGLsizei mWidth;
-    WebGLsizei mHeight;
+    GLsizei mWidth;
+    GLsizei mHeight;
 };
 
 }// namespace mozilla
 
 template <typename T>
 inline void
 ImplCycleCollectionUnlink(mozilla::WebGLRefPtr<T>& aField)
 {
--- a/content/canvas/src/WebGLProgram.cpp
+++ b/content/canvas/src/WebGLProgram.cpp
@@ -2,16 +2,17 @@
 /* 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/. */
 
 #include "WebGLContext.h"
 #include "WebGLShader.h"
 #include "WebGLProgram.h"
 #include "mozilla/dom/WebGLRenderingContextBinding.h"
+#include "GLContext.h"
 
 using namespace mozilla;
 
 /** Takes an ASCII string like "foo[i]", turns it into "foo" and returns "[i]" in bracketPart
   * 
   * \param string input/output: the string to split, becomes the string without the bracket part
   * \param bracketPart output: gets the bracket part.
   * 
--- a/content/canvas/src/WebGLProgram.h
+++ b/content/canvas/src/WebGLProgram.h
@@ -7,16 +7,17 @@
 #define WEBGLPROGRAM_H_
 
 #include "WebGLObjectModel.h"
 
 #include "nsWrapperCache.h"
 
 #include "mozilla/LinkedList.h"
 #include "mozilla/CheckedInt.h"
+#include <map>
 
 namespace mozilla {
 
 class WebGLShader;
 class WebGLUniformInfo;
 
 typedef nsDataHashtable<nsCStringHashKey, nsCString> CStringMap;
 typedef nsDataHashtable<nsCStringHashKey, WebGLUniformInfo> CStringToUniformInfoMap;
@@ -35,17 +36,17 @@ public:
     }
 
     void Delete();
 
     void DetachShaders() {
         mAttachedShaders.Clear();
     }
 
-    WebGLuint GLName() { return mGLName; }
+    GLuint GLName() { return mGLName; }
     const nsTArray<WebGLRefPtr<WebGLShader> >& AttachedShaders() const { return mAttachedShaders; }
     bool LinkStatus() { return mLinkStatus; }
     uint32_t Generation() const { return mGeneration.value(); }
     void SetLinkStatus(bool val) { mLinkStatus = val; }
 
     bool ContainsShader(WebGLShader *shader) {
         return mAttachedShaders.Contains(shader);
     }
@@ -109,17 +110,17 @@ public:
     NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(WebGLProgram)
     NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(WebGLProgram)
 
     // public post-link data
     std::map<GLint, nsCString> mActiveAttribMap;
 
 protected:
 
-    WebGLuint mGLName;
+    GLuint mGLName;
     bool mLinkStatus;
     // attached shaders of the program object
     nsTArray<WebGLRefPtr<WebGLShader> > mAttachedShaders;
     CheckedUint32 mGeneration;
 
     // post-link data
     nsTArray<bool> mAttribsInUse;
     nsAutoPtr<CStringMap> mIdentifierMap, mIdentifierReverseMap;
--- a/content/canvas/src/WebGLQuery.cpp
+++ b/content/canvas/src/WebGLQuery.cpp
@@ -1,14 +1,15 @@
 /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
 /* 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/. */
 
 #include "WebGLContext.h"
+#include "GLContext.h"
 #include "WebGLQuery.h"
 #include "mozilla/dom/WebGL2RenderingContextBinding.h"
 #include "nsContentUtils.h"
 
 using namespace mozilla;
 
 JSObject*
 WebGLQuery::WrapObject(JSContext *cx, JS::Handle<JSObject*> scope) {
@@ -28,18 +29,22 @@ WebGLQuery::WebGLQuery(WebGLContext* con
 }
 
 void WebGLQuery::Delete() {
     mContext->MakeContextCurrent();
     mContext->gl->fDeleteQueries(1, &mGLName);
     LinkedListElement<WebGLQuery>::removeFrom(mContext->mQueries);
 }
 
+bool WebGLQuery::IsActive() const
+{
+    WebGLRefPtr<WebGLQuery>* targetSlot = mContext->GetQueryTargetSlot(mType, "WebGLQuery::IsActive()");
+
+    MOZ_ASSERT(targetSlot, "unknown query object's type");
+
+    return *targetSlot == this;
+}
+
 
 NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_0(WebGLQuery)
 
-NS_IMPL_CYCLE_COLLECTING_ADDREF(WebGLQuery)
-NS_IMPL_CYCLE_COLLECTING_RELEASE(WebGLQuery)
-
-NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(WebGLQuery)
-  NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
-  NS_INTERFACE_MAP_ENTRY(nsISupports)
-NS_INTERFACE_MAP_END
+NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(WebGLQuery, AddRef)
+NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(WebGLQuery, Release)
--- a/content/canvas/src/WebGLQuery.h
+++ b/content/canvas/src/WebGLQuery.h
@@ -2,30 +2,28 @@
 /* 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/. */
 
 #ifndef WEBGLQUERY_H_
 #define WEBGLQUERY_H_
 
 #include "WebGLObjectModel.h"
-#include "WebGLContext.h"
 
 #include "nsWrapperCache.h"
 
 #include "mozilla/LinkedList.h"
 
 namespace mozilla {
 
 class WebGLQuery MOZ_FINAL
-    : public nsISupports
+    : public nsWrapperCache
     , public WebGLRefCountedObject<WebGLQuery>
     , public LinkedListElement<WebGLQuery>
     , public WebGLContextBoundObject
-    , public nsWrapperCache
 {
 // -----------------------------------------------------------------------------
 // PUBLIC
 public:
 
     // -------------------------------------------------------------------------
     // CONSTRUCTOR & DESTRUCTOR
 
@@ -34,24 +32,17 @@ public:
     ~WebGLQuery() {
         DeleteOnce();
     };
 
 
     // -------------------------------------------------------------------------
     // MEMBER FUNCTIONS
 
-    bool IsActive() const
-    {
-        WebGLRefPtr<WebGLQuery>* targetSlot = mContext->GetQueryTargetSlot(mType, "WebGLQuery::IsActive()");
-
-        MOZ_ASSERT(targetSlot, "unknown query object's type");
-
-        return *targetSlot == this;
-    }
+    bool IsActive() const;
 
     bool HasEverBeenActive()
     {
         return mType != 0;
     }
 
 
     // -------------------------------------------------------------------------
@@ -65,28 +56,28 @@ public:
     }
 
 
     // -------------------------------------------------------------------------
     // IMPLEMENT NS
     virtual JSObject* WrapObject(JSContext *cx,
                                  JS::Handle<JSObject*> scope) MOZ_OVERRIDE;
 
-    NS_DECL_CYCLE_COLLECTING_ISUPPORTS
-    NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(WebGLQuery)
+    NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(WebGLQuery)
+    NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(WebGLQuery)
 
 
 // -----------------------------------------------------------------------------
 // PRIVATE
 private:
 
     // -------------------------------------------------------------------------
     // MEMBERS
-    WebGLuint mGLName;
-    WebGLenum mType;
+    GLuint mGLName;
+    GLenum mType;
 
     // -------------------------------------------------------------------------
     // FRIENDSHIPS
     friend class WebGLContext;
 };
 
 } // namespace mozilla
 
--- a/content/canvas/src/WebGLRenderbuffer.cpp
+++ b/content/canvas/src/WebGLRenderbuffer.cpp
@@ -2,16 +2,17 @@
 /* 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/. */
 
 #include "WebGLContext.h"
 #include "WebGLRenderbuffer.h"
 #include "WebGLTexture.h"
 #include "mozilla/dom/WebGLRenderingContextBinding.h"
+#include "GLContext.h"
 
 using namespace mozilla;
 
 JSObject*
 WebGLRenderbuffer::WrapObject(JSContext *cx, JS::Handle<JSObject*> scope) {
     return dom::WebGLRenderbufferBinding::Wrap(cx, scope, this);
 }
 
--- a/content/canvas/src/WebGLRenderbuffer.h
+++ b/content/canvas/src/WebGLRenderbuffer.h
@@ -27,44 +27,44 @@ public:
     ~WebGLRenderbuffer() {
         DeleteOnce();
     }
 
     void Delete();
 
     bool HasEverBeenBound() { return mHasEverBeenBound; }
     void SetHasEverBeenBound(bool x) { mHasEverBeenBound = x; }
-    WebGLuint GLName() const { return mGLName; }
+    GLuint GLName() const { return mGLName; }
 
     bool Initialized() const { return mInitialized; }
     void SetInitialized(bool aInitialized) { mInitialized = aInitialized; }
 
-    WebGLenum InternalFormat() const { return mInternalFormat; }
-    void SetInternalFormat(WebGLenum aInternalFormat) { mInternalFormat = aInternalFormat; }
+    GLenum InternalFormat() const { return mInternalFormat; }
+    void SetInternalFormat(GLenum aInternalFormat) { mInternalFormat = aInternalFormat; }
 
-    WebGLenum InternalFormatForGL() const { return mInternalFormatForGL; }
-    void SetInternalFormatForGL(WebGLenum aInternalFormatForGL) { mInternalFormatForGL = aInternalFormatForGL; }
+    GLenum InternalFormatForGL() const { return mInternalFormatForGL; }
+    void SetInternalFormatForGL(GLenum aInternalFormatForGL) { mInternalFormatForGL