dom/xbl/nsXBLProtoImpl.h
author Timothy Nikkel <tnikkel@gmail.com>
Mon, 22 Aug 2016 21:15:38 -0500
changeset 310763 54933b5b96f1673a94a6463baf2c9cc643973e2d
parent 282097 114ec4ff6d65378cfe3d86f1af3e5c7aae855a09
child 313382 f0e7ef6f72894a499815393b6270fbbf088c19ad
permissions -rw-r--r--
Bug 1260324. Don't draw garbage to the screen if an image doesn't happen to be decoded. r=seth Layout has been using imgIContainer::IsOpaque to determine if the image will draw opaquely to all pixels it covers, and doing culling based on this. However imgIContainer::IsOpaque doesn't guarantee anything. It only describes if the image, when in a decoded state, has all opaque pixels. So if the image doesn't have fully decoded frames around (because they got discarded) it may not draw opaquely to all of its pixels. So we create a new function that first checks if there is a fully decoded frame.

/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* 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 nsXBLProtoImpl_h__
#define nsXBLProtoImpl_h__

#include "nsMemory.h"
#include "nsXBLPrototypeHandler.h"
#include "nsXBLProtoImplMember.h"
#include "nsXBLProtoImplField.h"
#include "nsXBLBinding.h"

class nsXBLPrototypeBinding;
class nsXBLProtoImplAnonymousMethod;

class nsXBLProtoImpl final
{
public:
  nsXBLProtoImpl()
    : mPrecompiledMemberHolder(nullptr),
      mMembers(nullptr),
      mFields(nullptr),
      mConstructor(nullptr),
      mDestructor(nullptr)
  {
    MOZ_COUNT_CTOR(nsXBLProtoImpl);
  }
  ~nsXBLProtoImpl()
  {
    MOZ_COUNT_DTOR(nsXBLProtoImpl);
    // Note: the constructor and destructor are in mMembers, so we'll
    // clean them up automatically.
    delete mMembers;
    delete mFields;
  }


  nsresult InstallImplementation(nsXBLPrototypeBinding* aPrototypeBinding, nsXBLBinding* aBinding);

private:
  nsresult InitTargetObjects(nsXBLPrototypeBinding* aBinding,
                             nsIContent* aBoundElement,
                             JS::MutableHandle<JSObject*> aTargetClassObject,
                             bool* aTargetIsNew);

public:
  nsresult CompilePrototypeMembers(nsXBLPrototypeBinding* aBinding);

  bool LookupMember(JSContext* aCx, nsString& aName, JS::Handle<jsid> aNameAsId,
                    JS::MutableHandle<JS::PropertyDescriptor> aDesc,
                    JS::Handle<JSObject*> aClassObject);

  void SetMemberList(nsXBLProtoImplMember* aMemberList)
  {
    delete mMembers;
    mMembers = aMemberList;
  }

  void SetFieldList(nsXBLProtoImplField* aFieldList)
  {
    delete mFields;
    mFields = aFieldList;
  }

  void Trace(const TraceCallbacks& aCallbacks, void *aClosure);
  void UnlinkJSObjects();

  nsXBLProtoImplField* FindField(const nsString& aFieldName) const;

  // Resolve all the fields for this implementation on the object |obj| False
  // return means a JS exception was set.
  bool ResolveAllFields(JSContext *cx, JS::Handle<JSObject*> obj) const;

  // Undefine all our fields from object |obj| (which should be a
  // JSObject for a bound element).
  void UndefineFields(JSContext* cx, JS::Handle<JSObject*> obj) const;

  bool CompiledMembers() const {
    return mPrecompiledMemberHolder != nullptr;
  }

  nsresult Read(nsIObjectInputStream* aStream,
                nsXBLPrototypeBinding* aBinding);
  nsresult Write(nsIObjectOutputStream* aStream,
                 nsXBLPrototypeBinding* aBinding);

protected:
  // used by Read to add each member
  nsXBLProtoImplMember* AddMember(nsXBLProtoImplMember* aMember,
                                  nsXBLProtoImplMember* aPreviousMember)
  {
    if (aPreviousMember)
      aPreviousMember->SetNext(aMember);
    else
      mMembers = aMember;
    return aMember;
  }

  void DestroyMembers();

public:
  nsString mClassName; // The name of the class.

protected:
  JSObject* mPrecompiledMemberHolder; // The class object for the binding. We'll use this to pre-compile properties
                          // and methods for the binding.

  nsXBLProtoImplMember* mMembers; // The members of an implementation are chained in this singly-linked list.

  nsXBLProtoImplField* mFields; // Our fields

public:
  nsXBLProtoImplAnonymousMethod* mConstructor; // Our class constructor.
  nsXBLProtoImplAnonymousMethod* mDestructor;  // Our class destructor.
};

nsresult
NS_NewXBLProtoImpl(nsXBLPrototypeBinding* aBinding,
                   const char16_t* aClassName,
                   nsXBLProtoImpl** aResult);

#endif // nsXBLProtoImpl_h__