author Doug Thayer <dothayer@mozilla.com>
Fri, 01 Mar 2019 18:29:09 +0000
changeset 520116 8b3fe0426ffc1b3a2ad044ef6cdde6c4f736f8e2
parent 505383 6f3709b3878117466168c40affa7bca0b60cf75b
child 530873 e1993a1f09ac53cd1a04fdf6a87f8cad8e44f73e
permissions -rw-r--r--
Bug 1442694 - Fix failures due to removing selected tab r=Gijs This adds test which reproduce the failure as well as the fix. Essentially, if we hit the edited case in SessionStore with `tab` equal to `tabbrowser.tabs[t]`, we remove the tab and then try to pin it, which obviously blows up. Note: the additional method in SessionStore.jsm was largely to get around complexity requirements inside restoreWindow. Cleaner solutions welcome. Differential Revision: https://phabricator.services.mozilla.com/D21383

/* vim: se cin sw=2 ts=2 et : */
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
 * 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 __mozilla_widget_GfxInfoCollector_h__
#define __mozilla_widget_GfxInfoCollector_h__

#include "mozilla/Attributes.h"
#include "nsStringFwd.h"
#include "js/RootingAPI.h"

namespace mozilla {
namespace widget {

/* this is handy wrapper around JSAPI to make it more pleasant to use.
 * We collect the JSAPI errors and so that callers don't need to */
class MOZ_STACK_CLASS InfoObject {
  friend class GfxInfoBase;

  void DefineProperty(const char *name, int value);
  void DefineProperty(const char *name, nsAString &value);
  void DefineProperty(const char *name, const char *value);

  // We need to ensure that this object lives on the stack so that GC sees it
  // properly
  explicit InfoObject(JSContext *aCx);
  InfoObject(InfoObject &);

  JSContext *mCx;
  JS::Rooted<JSObject *> mObj;
  bool mOk;


   Here's an example usage:

   class Foo {
   Foo::Foo() : mInfoCollector(this, &Foo::GetAweseomeness) {}

   void GetAwesomeness(InfoObject &obj) {
     obj.DefineProperty("awesome", mAwesome);

   int mAwesome;

   GfxInfoCollector<Foo> mInfoCollector;

   This will define a property on the object
   returned from calling getInfo() on a
   GfxInfo object. e.g.

       gfxInfo = Cc["@mozilla.org/gfx/info;1"].getService(Ci.nsIGfxInfo);
       info = gfxInfo.getInfo();
       if (info.awesome)


class GfxInfoCollectorBase {
  virtual void GetInfo(InfoObject &obj) = 0;
  virtual ~GfxInfoCollectorBase();

template <class T>
class GfxInfoCollector : public GfxInfoCollectorBase {
  GfxInfoCollector(T *aPointer, void (T::*aFunc)(InfoObject &obj))
      : mPointer(aPointer), mFunc(aFunc) {}
  virtual void GetInfo(InfoObject &obj) override { (mPointer->*mFunc)(obj); }

  T *mPointer;
  void (T::*mFunc)(InfoObject &obj);

}  // namespace widget
}  // namespace mozilla