зеркало из https://github.com/mozilla/gecko-dev.git
Merge m-c to inbound, a=merge
This commit is contained in:
Коммит
9abb1e1c41
|
@ -4184,12 +4184,6 @@
|
|||
</certItem>
|
||||
<certItem issuerName="ME0xCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxJzAlBgNVBAMTHkRpZ2lDZXJ0IFNIQTIgU2VjdXJlIFNlcnZlciBDQQ==">
|
||||
<serialNumber>Aa8e+91erglSMgsk/mtVaA==</serialNumber>
|
||||
</certItem>
|
||||
<certItem issuerName="MEcxCzAJBgNVBAYTAkhLMRYwFAYDVQQKEw1Ib25na29uZyBQb3N0MSAwHgYDVQQDExdIb25na29uZyBQb3N0IFJvb3QgQ0EgMQ==">
|
||||
<serialNumber>BHk=</serialNumber>
|
||||
</certItem>
|
||||
<certItem issuerName="MEcxCzAJBgNVBAYTAkhLMRYwFAYDVQQKEw1Ib25na29uZyBQb3N0MSAwHgYDVQQDExdIb25na29uZyBQb3N0IFJvb3QgQ0EgMQ==">
|
||||
<serialNumber>BHk=</serialNumber>
|
||||
</certItem>
|
||||
</certItems>
|
||||
|
||||
|
|
|
@ -475,8 +475,12 @@ toolbar:not(#TabsToolbar) > #personal-bookmarks {
|
|||
display: none;
|
||||
}
|
||||
|
||||
#PopupAutoComplete {
|
||||
-moz-binding: url("chrome://browser/content/urlbarBindings.xml#browser-autocomplete-result-popup");
|
||||
#PopupAutoComplete > richlistbox > richlistitem > .ac-type-icon,
|
||||
#PopupAutoComplete > richlistbox > richlistitem > .ac-site-icon,
|
||||
#PopupAutoComplete > richlistbox > richlistitem > .ac-tags,
|
||||
#PopupAutoComplete > richlistbox > richlistitem > .ac-separator,
|
||||
#PopupAutoComplete > richlistbox > richlistitem > .ac-url {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#PopupSearchAutoComplete {
|
||||
|
|
|
@ -141,7 +141,7 @@
|
|||
<tooltip id="remoteBrowserTooltip"/>
|
||||
|
||||
<!-- for search and content formfill/pw manager -->
|
||||
<panel type="autocomplete" id="PopupAutoComplete" noautofocus="true" hidden="true"/>
|
||||
<panel type="autocomplete-richlistbox" id="PopupAutoComplete" noautofocus="true" hidden="true"/>
|
||||
|
||||
<!-- for search with one-off buttons -->
|
||||
<panel type="autocomplete" id="PopupSearchAutoComplete" noautofocus="true" hidden="true"/>
|
||||
|
|
|
@ -914,6 +914,10 @@ notification[value="translation"] menulist > .menulist-dropmarker {
|
|||
display: block;
|
||||
}
|
||||
|
||||
/* AutoComplete */
|
||||
|
||||
%include ../shared/autocomplete.inc.css
|
||||
|
||||
#treecolAutoCompleteImage {
|
||||
max-width : 36px;
|
||||
}
|
||||
|
|
|
@ -1750,6 +1750,8 @@ toolbar .toolbarbutton-1 > .toolbarbutton-menubutton-button {
|
|||
|
||||
/* ----- AUTOCOMPLETE ----- */
|
||||
|
||||
%include ../shared/autocomplete.inc.css
|
||||
|
||||
#treecolAutoCompleteImage {
|
||||
max-width: 36px;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
%if 0
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
%endif
|
||||
|
||||
#PopupAutoComplete > richlistbox > richlistitem {
|
||||
height: 20px;
|
||||
min-height: 20px;
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
#PopupAutoComplete > richlistbox > richlistitem > .ac-title {
|
||||
font: icon;
|
||||
margin-inline-start: 6px;
|
||||
}
|
||||
|
||||
#PopupAutoComplete > richlistbox {
|
||||
padding: 0;
|
||||
}
|
|
@ -1532,6 +1532,8 @@ html|*.urlbar-input:-moz-lwtheme::placeholder,
|
|||
|
||||
/* autocomplete */
|
||||
|
||||
%include ../shared/autocomplete.inc.css
|
||||
|
||||
#treecolAutoCompleteImage {
|
||||
max-width: 36px;
|
||||
}
|
||||
|
|
|
@ -33,6 +33,15 @@ const int kLeftStickYAxis = 1;
|
|||
const int kRightStickXAxis = 2;
|
||||
const int kRightStickYAxis = 3;
|
||||
|
||||
// Standard channel is used for managing gamepads that
|
||||
// are from GamepadPlatformService. VR channel
|
||||
// is for gamepads that are from VRManagerChild.
|
||||
enum class GamepadServiceType : uint16_t {
|
||||
Standard,
|
||||
VR,
|
||||
NumGamepadServiceType
|
||||
};
|
||||
|
||||
class Gamepad final : public nsISupports,
|
||||
public nsWrapperCache
|
||||
{
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
#include "nsIObserverService.h"
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsThreadUtils.h"
|
||||
#include "VRManagerChild.h"
|
||||
#include "mozilla/Services.h"
|
||||
#include "mozilla/Unused.h"
|
||||
|
||||
|
@ -50,6 +51,7 @@ const nsTArray<RefPtr<nsGlobalWindow>>::index_type NoIndex =
|
|||
bool sShutdown = false;
|
||||
|
||||
StaticRefPtr<GamepadManager> gGamepadManagerSingleton;
|
||||
const uint32_t VR_GAMEPAD_IDX_OFFSET = 0x01 << 16;
|
||||
|
||||
} // namespace
|
||||
|
||||
|
@ -108,6 +110,11 @@ GamepadManager::StopMonitoring()
|
|||
}
|
||||
mChannelChildren.Clear();
|
||||
mGamepads.Clear();
|
||||
|
||||
#if defined(XP_WIN) || defined(XP_MACOSX) || defined(XP_LINUX)
|
||||
mVRChannelChild = gfx::VRManagerChild::Get();
|
||||
mVRChannelChild->SendControllerListenerRemoved();
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -188,10 +195,36 @@ GamepadManager::GetGamepad(uint32_t aIndex) const
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
uint32_t GamepadManager::GetGamepadIndexWithServiceType(uint32_t aIndex,
|
||||
GamepadServiceType aServiceType)
|
||||
{
|
||||
uint32_t newIndex = 0;
|
||||
|
||||
switch (aServiceType) {
|
||||
case GamepadServiceType::Standard:
|
||||
{
|
||||
MOZ_ASSERT(aIndex <= VR_GAMEPAD_IDX_OFFSET);
|
||||
newIndex = aIndex;
|
||||
break;
|
||||
}
|
||||
case GamepadServiceType::VR:
|
||||
{
|
||||
newIndex = aIndex + VR_GAMEPAD_IDX_OFFSET;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
MOZ_ASSERT(false);
|
||||
break;
|
||||
}
|
||||
|
||||
return newIndex;
|
||||
}
|
||||
|
||||
void
|
||||
GamepadManager::AddGamepad(uint32_t aIndex,
|
||||
const nsAString& aId,
|
||||
GamepadMappingType aMapping,
|
||||
GamepadServiceType aServiceType,
|
||||
uint32_t aNumButtons,
|
||||
uint32_t aNumAxes)
|
||||
{
|
||||
|
@ -204,24 +237,28 @@ GamepadManager::AddGamepad(uint32_t aIndex,
|
|||
aNumButtons,
|
||||
aNumAxes);
|
||||
|
||||
uint32_t newIndex = GetGamepadIndexWithServiceType(aIndex, aServiceType);
|
||||
|
||||
// We store the gamepad related to its index given by the parent process,
|
||||
// and no duplicate index is allowed.
|
||||
MOZ_ASSERT(!mGamepads.Get(aIndex, nullptr));
|
||||
mGamepads.Put(aIndex, gamepad);
|
||||
NewConnectionEvent(aIndex, true);
|
||||
MOZ_ASSERT(!mGamepads.Get(newIndex, nullptr));
|
||||
mGamepads.Put(newIndex, gamepad);
|
||||
NewConnectionEvent(newIndex, true);
|
||||
}
|
||||
|
||||
void
|
||||
GamepadManager::RemoveGamepad(uint32_t aIndex)
|
||||
GamepadManager::RemoveGamepad(uint32_t aIndex, GamepadServiceType aServiceType)
|
||||
{
|
||||
RefPtr<Gamepad> gamepad = GetGamepad(aIndex);
|
||||
uint32_t newIndex = GetGamepadIndexWithServiceType(aIndex, aServiceType);
|
||||
|
||||
RefPtr<Gamepad> gamepad = GetGamepad(newIndex);
|
||||
if (!gamepad) {
|
||||
NS_WARNING("Trying to delete gamepad with invalid index");
|
||||
return;
|
||||
}
|
||||
gamepad->SetConnected(false);
|
||||
NewConnectionEvent(aIndex, false);
|
||||
mGamepads.Remove(aIndex);
|
||||
NewConnectionEvent(newIndex, false);
|
||||
mGamepads.Remove(newIndex);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -544,13 +581,13 @@ GamepadManager::Update(const GamepadChangeEvent& aEvent)
|
|||
if (aEvent.type() == GamepadChangeEvent::TGamepadAdded) {
|
||||
const GamepadAdded& a = aEvent.get_GamepadAdded();
|
||||
AddGamepad(a.index(), a.id(),
|
||||
static_cast<GamepadMappingType>(a.mapping()),
|
||||
a.mapping(), a.service_type(),
|
||||
a.num_buttons(), a.num_axes());
|
||||
return;
|
||||
}
|
||||
if (aEvent.type() == GamepadChangeEvent::TGamepadRemoved) {
|
||||
const GamepadRemoved& a = aEvent.get_GamepadRemoved();
|
||||
RemoveGamepad(a.index());
|
||||
RemoveGamepad(a.index(), a.service_type());
|
||||
return;
|
||||
}
|
||||
if (aEvent.type() == GamepadChangeEvent::TGamepadButtonInformation) {
|
||||
|
@ -584,8 +621,13 @@ GamepadManager::ActorCreated(PBackgroundChild *aActor)
|
|||
child->SendGamepadListenerAdded();
|
||||
mChannelChildren.AppendElement(child);
|
||||
|
||||
// TODO: Add more event channels to mChannelChildren if you would
|
||||
// like to support more kinds of devices.
|
||||
#if defined(XP_WIN) || defined(XP_MACOSX) || defined(XP_LINUX)
|
||||
// Construct VRManagerChannel and ask adding the connected
|
||||
// VR controllers to GamepadManager
|
||||
mVRChannelChild = gfx::VRManagerChild::Get();
|
||||
mVRChannelChild->SetGamepadManager(this);
|
||||
mVRChannelChild->SendControllerListenerAdded();
|
||||
#endif
|
||||
}
|
||||
|
||||
//Override nsIIPCBackgroundChildCreateCallback
|
||||
|
|
|
@ -15,6 +15,9 @@
|
|||
class nsGlobalWindow;
|
||||
|
||||
namespace mozilla {
|
||||
namespace gfx {
|
||||
class VRManagerChild;
|
||||
} // namespace gfx
|
||||
namespace dom {
|
||||
|
||||
class EventTarget;
|
||||
|
@ -47,10 +50,10 @@ class GamepadManager final : public nsIObserver,
|
|||
|
||||
// Add a gamepad to the list of known gamepads.
|
||||
void AddGamepad(uint32_t aIndex, const nsAString& aID, GamepadMappingType aMapping,
|
||||
uint32_t aNumButtons, uint32_t aNumAxes);
|
||||
GamepadServiceType aServiceType, uint32_t aNumButtons, uint32_t aNumAxes);
|
||||
|
||||
// Remove the gamepad at |aIndex| from the list of known gamepads.
|
||||
void RemoveGamepad(uint32_t aIndex);
|
||||
void RemoveGamepad(uint32_t aIndex, GamepadServiceType aServiceType);
|
||||
|
||||
// Update the state of |aButton| for the gamepad at |aIndex| for all
|
||||
// windows that are listening and visible, and fire one of
|
||||
|
@ -113,6 +116,7 @@ class GamepadManager final : public nsIObserver,
|
|||
// will be destroyed during the IPDL shutdown chain, so we
|
||||
// don't need to refcount it here.
|
||||
nsTArray<GamepadEventChannelChild *> mChannelChildren;
|
||||
gfx::VRManagerChild* mVRChannelChild;
|
||||
|
||||
private:
|
||||
|
||||
|
@ -127,6 +131,9 @@ class GamepadManager final : public nsIObserver,
|
|||
// Indicate that a window has received data from a gamepad.
|
||||
void SetWindowHasSeenGamepad(nsGlobalWindow* aWindow, uint32_t aIndex,
|
||||
bool aHasSeen = true);
|
||||
// Our gamepad index has VR_GAMEPAD_IDX_OFFSET while GamepadChannelType
|
||||
// is from VRManager.
|
||||
uint32_t GetGamepadIndexWithServiceType(uint32_t aIndex, GamepadServiceType aServiceType);
|
||||
|
||||
// Gamepads connected to the system. Copies of these are handed out
|
||||
// to each window.
|
||||
|
|
|
@ -87,7 +87,7 @@ GamepadPlatformService::AddGamepad(const char* aID,
|
|||
|
||||
uint32_t index = ++mGamepadIndex;
|
||||
GamepadAdded a(NS_ConvertUTF8toUTF16(nsDependentCString(aID)), index,
|
||||
(uint32_t)aMapping, aNumButtons, aNumAxes);
|
||||
aMapping, GamepadServiceType::Standard, aNumButtons, aNumAxes);
|
||||
NotifyGamepadChange<GamepadAdded>(a);
|
||||
return index;
|
||||
}
|
||||
|
@ -99,7 +99,7 @@ GamepadPlatformService::RemoveGamepad(uint32_t aIndex)
|
|||
// platform-dependent backends
|
||||
MOZ_ASSERT(XRE_IsParentProcess());
|
||||
MOZ_ASSERT(!NS_IsMainThread());
|
||||
GamepadRemoved a(aIndex);
|
||||
GamepadRemoved a(aIndex, GamepadServiceType::Standard);
|
||||
NotifyGamepadChange<GamepadRemoved>(a);
|
||||
}
|
||||
|
||||
|
|
|
@ -122,8 +122,12 @@ GamepadServiceTest::AddGamepad(const nsAString& aID,
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
// Because GamepadServiceTest::AddGamepad() is opened for Web API,
|
||||
// we need to convert aMapping from uint32_t to GamepadMappingType here.
|
||||
GamepadAdded a(nsString(aID), 0,
|
||||
(uint32_t)aMapping, aNumButtons, aNumAxes);
|
||||
static_cast<GamepadMappingType>(aMapping),
|
||||
GamepadServiceType::Standard,
|
||||
aNumButtons, aNumAxes);
|
||||
GamepadChangeEvent e(a);
|
||||
nsCOMPtr<nsIGlobalObject> go = do_QueryInterface(mWindow);
|
||||
|
||||
|
@ -150,7 +154,7 @@ GamepadServiceTest::RemoveGamepad(uint32_t aIndex)
|
|||
return;
|
||||
}
|
||||
|
||||
GamepadRemoved a(aIndex);
|
||||
GamepadRemoved a(aIndex, GamepadServiceType::Standard);
|
||||
GamepadChangeEvent e(a);
|
||||
|
||||
uint32_t id = ++mEventNumber;
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#define mozilla_dom_GamepadServiceTest_h_
|
||||
|
||||
#include "nsIIPCBackgroundChildCreateCallback.h"
|
||||
#include "mozilla/dom/GamepadBinding.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
|
|
@ -2,19 +2,25 @@
|
|||
* 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/. */
|
||||
|
||||
using mozilla::dom::GamepadMappingType from "mozilla/dom/GamepadMessageUtils.h";
|
||||
using mozilla::dom::GamepadServiceType from "mozilla/dom/GamepadMessageUtils.h";
|
||||
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
struct GamepadAdded {
|
||||
nsString id;
|
||||
uint32_t index;
|
||||
uint32_t mapping;
|
||||
GamepadMappingType mapping;
|
||||
GamepadServiceType service_type;
|
||||
uint32_t num_buttons;
|
||||
uint32_t num_axes;
|
||||
};
|
||||
|
||||
struct GamepadRemoved {
|
||||
uint32_t index;
|
||||
GamepadServiceType service_type;
|
||||
};
|
||||
|
||||
struct GamepadAxisInformation {
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
|
||||
#ifndef mozilla_dom_gamepad_GamepadMessageUtils_h
|
||||
#define mozilla_dom_gamepad_GamepadMessageUtils_h
|
||||
|
||||
#include "ipc/IPCMessageUtils.h"
|
||||
#include "mozilla/dom/Gamepad.h"
|
||||
|
||||
namespace IPC {
|
||||
|
||||
template<>
|
||||
struct ParamTraits<mozilla::dom::GamepadMappingType> :
|
||||
public ContiguousEnumSerializer<mozilla::dom::GamepadMappingType,
|
||||
mozilla::dom::GamepadMappingType(mozilla::dom::GamepadMappingType::_empty),
|
||||
mozilla::dom::GamepadMappingType(mozilla::dom::GamepadMappingType::EndGuard_)> {};
|
||||
|
||||
template<>
|
||||
struct ParamTraits<mozilla::dom::GamepadServiceType> :
|
||||
public ContiguousEnumSerializer<mozilla::dom::GamepadServiceType,
|
||||
mozilla::dom::GamepadServiceType(0),
|
||||
mozilla::dom::GamepadServiceType(
|
||||
mozilla::dom::GamepadServiceType::NumGamepadServiceType)> {};
|
||||
} // namespace IPC
|
||||
|
||||
#endif // mozilla_dom_gamepad_GamepadMessageUtils_h
|
|
@ -23,7 +23,7 @@ GamepadTestChannelParent::RecvGamepadTestEvent(const uint32_t& aID,
|
|||
nsCString gamepadID;
|
||||
LossyCopyUTF16toASCII(a.id(), gamepadID);
|
||||
uint32_t index = service->AddGamepad(gamepadID.get(),
|
||||
(GamepadMappingType)a.mapping(),
|
||||
a.mapping(),
|
||||
a.num_buttons(),
|
||||
a.num_axes());
|
||||
if (!mShuttingdown) {
|
||||
|
|
|
@ -20,6 +20,7 @@ if CONFIG['MOZ_GAMEPAD']:
|
|||
'GamepadServiceTest.h',
|
||||
'ipc/GamepadEventChannelChild.h',
|
||||
'ipc/GamepadEventChannelParent.h',
|
||||
'ipc/GamepadMessageUtils.h',
|
||||
'ipc/GamepadTestChannelChild.h',
|
||||
'ipc/GamepadTestChannelParent.h'
|
||||
]
|
||||
|
|
|
@ -31,7 +31,6 @@ TextTrackList::TextTrackList(nsPIDOMWindowInner* aOwnerWindow)
|
|||
TextTrackList::TextTrackList(nsPIDOMWindowInner* aOwnerWindow,
|
||||
TextTrackManager* aTextTrackManager)
|
||||
: DOMEventTargetHelper(aOwnerWindow)
|
||||
, mPendingTextTrackChange(false)
|
||||
, mTextTrackManager(aTextTrackManager)
|
||||
{
|
||||
}
|
||||
|
|
|
@ -67,7 +67,7 @@ public:
|
|||
IMPL_EVENT_HANDLER(addtrack)
|
||||
IMPL_EVENT_HANDLER(removetrack)
|
||||
|
||||
bool mPendingTextTrackChange;
|
||||
bool mPendingTextTrackChange = false;
|
||||
|
||||
private:
|
||||
~TextTrackList();
|
||||
|
|
|
@ -19,7 +19,7 @@ using namespace mozilla;
|
|||
using namespace mozilla::gfx;
|
||||
using namespace mozilla::layers;
|
||||
|
||||
VRDisplayHost::VRDisplayHost(VRDisplayType aType)
|
||||
VRDisplayHost::VRDisplayHost(VRDeviceType aType)
|
||||
: mInputFrameID(0)
|
||||
{
|
||||
MOZ_COUNT_CTOR(VRDisplayHost);
|
||||
|
@ -144,3 +144,15 @@ VRDisplayHost::CheckClearDisplayInfoDirty()
|
|||
mLastUpdateDisplayInfo = mDisplayInfo;
|
||||
return true;
|
||||
}
|
||||
|
||||
VRControllerHost::VRControllerHost(VRDeviceType aType)
|
||||
{
|
||||
MOZ_COUNT_CTOR(VRControllerHost);
|
||||
mControllerInfo.mType = aType;
|
||||
mControllerInfo.mControllerID = VRDisplayManager::AllocateDisplayID();
|
||||
}
|
||||
|
||||
VRControllerHost::~VRControllerHost()
|
||||
{
|
||||
MOZ_COUNT_DTOR(VRControllerHost);
|
||||
}
|
|
@ -52,7 +52,7 @@ public:
|
|||
bool CheckClearDisplayInfoDirty();
|
||||
|
||||
protected:
|
||||
explicit VRDisplayHost(VRDisplayType aType);
|
||||
explicit VRDisplayHost(VRDeviceType aType);
|
||||
virtual ~VRDisplayHost();
|
||||
|
||||
#if defined(XP_WIN)
|
||||
|
@ -83,6 +83,19 @@ private:
|
|||
VRDisplayInfo mLastUpdateDisplayInfo;
|
||||
};
|
||||
|
||||
class VRControllerHost {
|
||||
public:
|
||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(VRControllerHost)
|
||||
|
||||
const VRControllerInfo& GetControllerInfo() const { return mControllerInfo; }
|
||||
|
||||
protected:
|
||||
explicit VRControllerHost(VRDeviceType aType);
|
||||
virtual ~VRControllerHost();
|
||||
|
||||
VRControllerInfo mControllerInfo;
|
||||
};
|
||||
|
||||
} // namespace gfx
|
||||
} // namespace mozilla
|
||||
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#include "gfxVROpenVR.h"
|
||||
#include "mozilla/ClearOnShutdown.h"
|
||||
#include "mozilla/dom/VRDisplay.h"
|
||||
#include "mozilla/dom/GamepadEventTypes.h"
|
||||
#include "mozilla/layers/TextureHost.h"
|
||||
#include "mozilla/Unused.h"
|
||||
|
||||
|
@ -51,6 +52,7 @@ VRManager::VRManager()
|
|||
MOZ_ASSERT(sVRManagerSingleton == nullptr);
|
||||
|
||||
RefPtr<VRDisplayManager> mgr;
|
||||
RefPtr<VRControllerManager> controllerMgr;
|
||||
|
||||
/**
|
||||
* We must add the VRDisplayManager's to mManagers in a careful order to
|
||||
|
@ -81,6 +83,11 @@ VRManager::VRManager()
|
|||
mManagers.AppendElement(mgr);
|
||||
}
|
||||
|
||||
controllerMgr = VRControllerManagerOpenVR::Create();
|
||||
if (mgr) {
|
||||
mControllerManagers.AppendElement(controllerMgr);
|
||||
}
|
||||
|
||||
// OSVR is cross platform compatible
|
||||
mgr = VRDisplayManagerOSVR::Create();
|
||||
if (mgr) {
|
||||
|
@ -103,6 +110,11 @@ VRManager::Destroy()
|
|||
for (uint32_t i = 0; i < mManagers.Length(); ++i) {
|
||||
mManagers[i]->Destroy();
|
||||
}
|
||||
|
||||
mVRControllers.Clear();
|
||||
for (uint32_t i = 0; i < mControllerManagers.Length(); ++i) {
|
||||
mControllerManagers[i]->Destroy();
|
||||
}
|
||||
mInitialized = false;
|
||||
}
|
||||
|
||||
|
@ -112,6 +124,10 @@ VRManager::Init()
|
|||
for (uint32_t i = 0; i < mManagers.Length(); ++i) {
|
||||
mManagers[i]->Init();
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < mControllerManagers.Length(); ++i) {
|
||||
mControllerManagers[i]->Init();
|
||||
}
|
||||
mInitialized = true;
|
||||
}
|
||||
|
||||
|
@ -169,12 +185,16 @@ VRManager::NotifyVsync(const TimeStamp& aVsyncTimestamp)
|
|||
if (mLastRefreshTime.IsNull()) {
|
||||
// This is the first vsync, must refresh VR displays
|
||||
RefreshVRDisplays();
|
||||
RefreshVRControllers();
|
||||
mLastRefreshTime = TimeStamp::Now();
|
||||
} else {
|
||||
// We don't have to do this every frame, so check if we
|
||||
// have refreshed recently.
|
||||
TimeDuration duration = TimeStamp::Now() - mLastRefreshTime;
|
||||
if (duration.ToMilliseconds() > kVRDisplayRefreshMaxDuration) {
|
||||
RefreshVRDisplays();
|
||||
RefreshVRControllers();
|
||||
mLastRefreshTime = TimeStamp::Now();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -236,8 +256,6 @@ VRManager::RefreshVRDisplays(bool aMustDispatch)
|
|||
if (displayInfoChanged || aMustDispatch) {
|
||||
DispatchVRDisplayInfoUpdate();
|
||||
}
|
||||
|
||||
mLastRefreshTime = TimeStamp::Now();
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -289,5 +307,82 @@ VRManager::SubmitFrame(VRLayerParent* aLayer, layers::PTextureParent* aTexture,
|
|||
}
|
||||
}
|
||||
|
||||
RefPtr<gfx::VRControllerHost>
|
||||
VRManager::GetController(const uint32_t& aControllerID)
|
||||
{
|
||||
RefPtr<gfx::VRControllerHost> controller;
|
||||
if (mVRControllers.Get(aControllerID, getter_AddRefs(controller))) {
|
||||
return controller;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void
|
||||
VRManager::GetVRControllerInfo(nsTArray<VRControllerInfo>& aControllerInfo)
|
||||
{
|
||||
aControllerInfo.Clear();
|
||||
for (auto iter = mVRControllers.Iter(); !iter.Done(); iter.Next()) {
|
||||
gfx::VRControllerHost* controller = iter.UserData();
|
||||
aControllerInfo.AppendElement(VRControllerInfo(controller->GetControllerInfo()));
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
VRManager::RefreshVRControllers()
|
||||
{
|
||||
nsTArray<RefPtr<gfx::VRControllerHost>> controllers;
|
||||
|
||||
for (uint32_t i = 0; i < mControllerManagers.Length()
|
||||
&& controllers.Length() == 0; ++i) {
|
||||
mControllerManagers[i]->GetControllers(controllers);
|
||||
}
|
||||
|
||||
bool controllerInfoChanged = false;
|
||||
|
||||
if (controllers.Length() != mVRControllers.Count()) {
|
||||
// Catch cases where VR controllers has been removed
|
||||
controllerInfoChanged = true;
|
||||
}
|
||||
|
||||
for (const auto& controller : controllers) {
|
||||
if (!GetController(controller->GetControllerInfo().GetControllerID())) {
|
||||
// This is a new controller
|
||||
controllerInfoChanged = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (controllerInfoChanged) {
|
||||
mVRControllers.Clear();
|
||||
for (const auto& controller : controllers) {
|
||||
mVRControllers.Put(controller->GetControllerInfo().GetControllerID(),
|
||||
controller);
|
||||
}
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < mControllerManagers.Length(); ++i) {
|
||||
mControllerManagers[i]->HandleInput();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
VRManager::ScanForDevices()
|
||||
{
|
||||
for (uint32_t i = 0; i < mControllerManagers.Length(); ++i) {
|
||||
mControllerManagers[i]->ScanForDevices();
|
||||
}
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void
|
||||
VRManager::NotifyGamepadChange(const T& aInfo)
|
||||
{
|
||||
dom::GamepadChangeEvent e(aInfo);
|
||||
|
||||
for (auto iter = mVRManagerParents.Iter(); !iter.Done(); iter.Next()) {
|
||||
Unused << iter.Get()->GetKey()->SendGamepadUpdate(e);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace gfx
|
||||
} // namespace mozilla
|
||||
|
|
|
@ -22,6 +22,7 @@ namespace gfx {
|
|||
class VRLayerParent;
|
||||
class VRManagerParent;
|
||||
class VRDisplayHost;
|
||||
class VRControllerManager;
|
||||
|
||||
class VRManager
|
||||
{
|
||||
|
@ -37,12 +38,16 @@ public:
|
|||
void NotifyVsync(const TimeStamp& aVsyncTimestamp);
|
||||
void NotifyVRVsync(const uint32_t& aDisplayID);
|
||||
void RefreshVRDisplays(bool aMustDispatch = false);
|
||||
void ScanForDevices();
|
||||
template<class T> void NotifyGamepadChange(const T& aInfo);
|
||||
RefPtr<gfx::VRDisplayHost> GetDisplay(const uint32_t& aDisplayID);
|
||||
void GetVRDisplayInfo(nsTArray<VRDisplayInfo>& aDisplayInfo);
|
||||
|
||||
void SubmitFrame(VRLayerParent* aLayer, layers::PTextureParent* aTexture,
|
||||
const gfx::Rect& aLeftEyeRect,
|
||||
const gfx::Rect& aRightEyeRect);
|
||||
RefPtr<gfx::VRControllerHost> GetController(const uint32_t& aControllerID);
|
||||
void GetVRControllerInfo(nsTArray<VRControllerInfo>& aControllerInfo);
|
||||
|
||||
protected:
|
||||
VRManager();
|
||||
|
@ -55,6 +60,7 @@ private:
|
|||
void Destroy();
|
||||
|
||||
void DispatchVRDisplayInfoUpdate();
|
||||
void RefreshVRControllers();
|
||||
|
||||
typedef nsTHashtable<nsRefPtrHashKey<VRManagerParent>> VRManagerParentSet;
|
||||
VRManagerParentSet mVRManagerParents;
|
||||
|
@ -62,9 +68,15 @@ private:
|
|||
typedef nsTArray<RefPtr<VRDisplayManager>> VRDisplayManagerArray;
|
||||
VRDisplayManagerArray mManagers;
|
||||
|
||||
typedef nsTArray<RefPtr<VRControllerManager>> VRControllerManagerArray;
|
||||
VRControllerManagerArray mControllerManagers;
|
||||
|
||||
typedef nsRefPtrHashtable<nsUint32HashKey, gfx::VRDisplayHost> VRDisplayHostHashMap;
|
||||
VRDisplayHostHashMap mVRDisplays;
|
||||
|
||||
typedef nsRefPtrHashtable<nsUint32HashKey, gfx::VRControllerHost> VRControllerHostHashMap;
|
||||
VRControllerHostHashMap mVRControllers;
|
||||
|
||||
Atomic<bool> mInitialized;
|
||||
|
||||
TimeStamp mLastRefreshTime;
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
#include <math.h>
|
||||
|
||||
#include "gfxVR.h"
|
||||
#include "mozilla/dom/Gamepad.h"
|
||||
|
||||
#ifndef M_PI
|
||||
# define M_PI 3.14159265358979323846
|
||||
|
@ -15,6 +16,7 @@ using namespace mozilla;
|
|||
using namespace mozilla::gfx;
|
||||
|
||||
Atomic<uint32_t> VRDisplayManager::sDisplayBase(0);
|
||||
Atomic<uint32_t> VRControllerManager::sControllerBase(0);
|
||||
|
||||
/* static */ uint32_t
|
||||
VRDisplayManager::AllocateDisplayID()
|
||||
|
@ -55,3 +57,34 @@ VRFieldOfView::ConstructProjectionMatrix(float zNear, float zFar,
|
|||
|
||||
return mobj;
|
||||
}
|
||||
|
||||
/* static */ uint32_t
|
||||
VRControllerManager::AllocateControllerID()
|
||||
{
|
||||
return ++sControllerBase;
|
||||
}
|
||||
|
||||
void
|
||||
VRControllerManager::AddGamepad(const char* aID,
|
||||
dom::GamepadMappingType aMapping,
|
||||
uint32_t aNumButtons, uint32_t aNumAxes)
|
||||
{
|
||||
dom::GamepadAdded a(NS_ConvertUTF8toUTF16(nsDependentCString(aID)), mControllerCount,
|
||||
aMapping, dom::GamepadServiceType::VR, aNumButtons,
|
||||
aNumAxes);
|
||||
|
||||
VRManager* vm = VRManager::Get();
|
||||
MOZ_ASSERT(vm);
|
||||
vm->NotifyGamepadChange<dom::GamepadAdded>(a);
|
||||
}
|
||||
|
||||
void
|
||||
VRControllerManager::NewButtonEvent(uint32_t aIndex, uint32_t aButton,
|
||||
bool aPressed, double aValue)
|
||||
{
|
||||
dom::GamepadButtonInformation a(aIndex, aButton, aPressed, aValue);
|
||||
|
||||
VRManager* vm = VRManager::Get();
|
||||
MOZ_ASSERT(vm);
|
||||
vm->NotifyGamepadChange<dom::GamepadButtonInformation>(a);
|
||||
}
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#include "mozilla/EnumeratedArray.h"
|
||||
#include "mozilla/TimeStamp.h"
|
||||
#include "mozilla/TypedEnumBits.h"
|
||||
#include "mozilla/dom/GamepadBinding.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
|
@ -23,12 +24,13 @@ class PTextureParent;
|
|||
namespace gfx {
|
||||
class VRLayerParent;
|
||||
class VRDisplayHost;
|
||||
class VRControllerHost;
|
||||
|
||||
enum class VRDisplayType : uint16_t {
|
||||
enum class VRDeviceType : uint16_t {
|
||||
Oculus,
|
||||
OpenVR,
|
||||
OSVR,
|
||||
NumVRDisplayTypes
|
||||
NumVRDeviceTypes
|
||||
};
|
||||
|
||||
enum class VRDisplayCapabilityFlags : uint16_t {
|
||||
|
@ -122,7 +124,7 @@ struct VRFieldOfView {
|
|||
|
||||
struct VRDisplayInfo
|
||||
{
|
||||
VRDisplayType GetType() const { return mType; }
|
||||
VRDeviceType GetType() const { return mType; }
|
||||
uint32_t GetDisplayID() const { return mDisplayID; }
|
||||
const nsCString& GetDisplayName() const { return mDisplayName; }
|
||||
VRDisplayCapabilityFlags GetCapabilities() const { return mCapabilityFlags; }
|
||||
|
@ -142,7 +144,7 @@ struct VRDisplayInfo
|
|||
};
|
||||
|
||||
uint32_t mDisplayID;
|
||||
VRDisplayType mType;
|
||||
VRDeviceType mType;
|
||||
nsCString mDisplayName;
|
||||
VRDisplayCapabilityFlags mCapabilityFlags;
|
||||
VRFieldOfView mEyeFOV[VRDisplayInfo::NumEyes];
|
||||
|
@ -209,6 +211,60 @@ protected:
|
|||
virtual ~VRDisplayManager() { }
|
||||
};
|
||||
|
||||
struct VRControllerInfo
|
||||
{
|
||||
VRDeviceType GetType() const { return mType; }
|
||||
uint32_t GetControllerID() const { return mControllerID; }
|
||||
const nsCString& GetControllerName() const { return mControllerName; }
|
||||
dom::GamepadMappingType GetMappingType() const { return mMappingType; }
|
||||
uint32_t GetNumButtons() const { return mNumButtons; }
|
||||
uint32_t GetNumAxes() const { return mNumAxes; }
|
||||
|
||||
uint32_t mControllerID;
|
||||
VRDeviceType mType;
|
||||
nsCString mControllerName;
|
||||
dom::GamepadMappingType mMappingType;
|
||||
uint32_t mNumButtons;
|
||||
uint32_t mNumAxes;
|
||||
|
||||
bool operator==(const VRControllerInfo& other) const {
|
||||
return mType == other.mType &&
|
||||
mControllerID == other.mControllerID &&
|
||||
mControllerName == other.mControllerName &&
|
||||
mMappingType == other.mMappingType &&
|
||||
mNumButtons == other.mNumButtons &&
|
||||
mNumAxes == other.mNumAxes;
|
||||
}
|
||||
|
||||
bool operator!=(const VRControllerInfo& other) const {
|
||||
return !(*this == other);
|
||||
}
|
||||
};
|
||||
|
||||
class VRControllerManager {
|
||||
public:
|
||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(VRControllerManager)
|
||||
|
||||
static uint32_t AllocateControllerID();
|
||||
virtual bool Init() = 0;
|
||||
virtual void Destroy() = 0;
|
||||
virtual void HandleInput() = 0;
|
||||
virtual void GetControllers(nsTArray<RefPtr<VRControllerHost>>& aControllerResult) = 0;
|
||||
virtual void ScanForDevices() = 0;
|
||||
void NewButtonEvent(uint32_t aIndex, uint32_t aButton,
|
||||
bool aPressed, double aValue);
|
||||
void AddGamepad(const char* aID, dom::GamepadMappingType aMapping,
|
||||
uint32_t aNumButtons, uint32_t aNumAxes);
|
||||
|
||||
protected:
|
||||
VRControllerManager() : mInstalled(false), mControllerCount(0) {}
|
||||
virtual ~VRControllerManager() {}
|
||||
|
||||
bool mInstalled;
|
||||
uint32_t mControllerCount;
|
||||
static Atomic<uint32_t> sControllerBase;
|
||||
};
|
||||
|
||||
} // namespace gfx
|
||||
} // namespace mozilla
|
||||
|
||||
|
|
|
@ -203,7 +203,7 @@ SetFromTanRadians(double left, double right, double bottom, double top)
|
|||
VRDisplayOSVR::VRDisplayOSVR(OSVR_ClientContext* context,
|
||||
OSVR_ClientInterface* iface,
|
||||
OSVR_DisplayConfig* display)
|
||||
: VRDisplayHost(VRDisplayType::OSVR)
|
||||
: VRDisplayHost(VRDeviceType::OSVR)
|
||||
, m_ctx(context)
|
||||
, m_iface(iface)
|
||||
, m_display(display)
|
||||
|
|
|
@ -315,7 +315,7 @@ FromFovPort(const ovrFovPort& aFOV)
|
|||
} // namespace
|
||||
|
||||
VRDisplayOculus::VRDisplayOculus(ovrSession aSession)
|
||||
: VRDisplayHost(VRDisplayType::Oculus)
|
||||
: VRDisplayHost(VRDeviceType::Oculus)
|
||||
, mSession(aSession)
|
||||
, mTextureSet(nullptr)
|
||||
, mQuadVS(nullptr)
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
#include "nsServiceManagerUtils.h"
|
||||
#include "nsIScreenManager.h"
|
||||
#include "openvr/openvr.h"
|
||||
#include "mozilla/dom/Gamepad.h"
|
||||
|
||||
#ifndef M_PI
|
||||
# define M_PI 3.14159265358979323846
|
||||
|
@ -33,6 +34,7 @@ using namespace mozilla;
|
|||
using namespace mozilla::gfx;
|
||||
using namespace mozilla::gfx::impl;
|
||||
using namespace mozilla::layers;
|
||||
using namespace mozilla::dom;
|
||||
|
||||
namespace {
|
||||
extern "C" {
|
||||
|
@ -85,7 +87,7 @@ LoadOpenVRRuntime()
|
|||
VRDisplayOpenVR::VRDisplayOpenVR(::vr::IVRSystem *aVRSystem,
|
||||
::vr::IVRChaperone *aVRChaperone,
|
||||
::vr::IVRCompositor *aVRCompositor)
|
||||
: VRDisplayHost(VRDisplayType::OpenVR)
|
||||
: VRDisplayHost(VRDeviceType::OpenVR)
|
||||
, mVRSystem(aVRSystem)
|
||||
, mVRChaperone(aVRChaperone)
|
||||
, mVRCompositor(aVRCompositor)
|
||||
|
@ -440,3 +442,142 @@ VRDisplayManagerOpenVR::GetHMDs(nsTArray<RefPtr<VRDisplayHost>>& aHMDResult)
|
|||
aHMDResult.AppendElement(mOpenVRHMD);
|
||||
}
|
||||
}
|
||||
|
||||
VRControllerOpenVR::VRControllerOpenVR()
|
||||
: VRControllerHost(VRDeviceType::OpenVR)
|
||||
{
|
||||
MOZ_COUNT_CTOR_INHERITED(VRControllerOpenVR, VRControllerHost);
|
||||
mControllerInfo.mControllerName.AssignLiteral("OpenVR HMD");
|
||||
}
|
||||
|
||||
VRControllerOpenVR::~VRControllerOpenVR()
|
||||
{
|
||||
MOZ_COUNT_DTOR_INHERITED(VRControllerOpenVR, VRControllerHost);
|
||||
}
|
||||
|
||||
VRControllerManagerOpenVR::VRControllerManagerOpenVR()
|
||||
: mOpenVRInstalled(false), mVRSystem(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
VRControllerManagerOpenVR::~VRControllerManagerOpenVR()
|
||||
{
|
||||
Destroy();
|
||||
}
|
||||
|
||||
/*static*/ already_AddRefed<VRControllerManagerOpenVR>
|
||||
VRControllerManagerOpenVR::Create()
|
||||
{
|
||||
if (!gfxPrefs::VREnabled() || !gfxPrefs::VROpenVREnabled()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
RefPtr<VRControllerManagerOpenVR> manager = new VRControllerManagerOpenVR();
|
||||
return manager.forget();
|
||||
}
|
||||
|
||||
bool
|
||||
VRControllerManagerOpenVR::Init()
|
||||
{
|
||||
if (mOpenVRInstalled)
|
||||
return true;
|
||||
|
||||
if (!vr_IsRuntimeInstalled())
|
||||
return false;
|
||||
|
||||
// Loading the OpenVR Runtime
|
||||
vr::EVRInitError err = vr::VRInitError_None;
|
||||
|
||||
vr_InitInternal(&err, vr::VRApplication_Scene);
|
||||
if (err != vr::VRInitError_None) {
|
||||
return false;
|
||||
}
|
||||
|
||||
mVRSystem = (vr::IVRSystem *)vr_GetGenericInterface(vr::IVRSystem_Version, &err);
|
||||
if ((err != vr::VRInitError_None) || !mVRSystem) {
|
||||
vr_ShutdownInternal();
|
||||
return false;
|
||||
}
|
||||
|
||||
mOpenVRInstalled = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
VRControllerManagerOpenVR::Destroy()
|
||||
{
|
||||
mOpenVRController.Clear();
|
||||
mOpenVRInstalled = false;
|
||||
}
|
||||
|
||||
void
|
||||
VRControllerManagerOpenVR::HandleInput()
|
||||
{
|
||||
MOZ_ASSERT(mVRSystem);
|
||||
|
||||
// Process OpenVR controller state
|
||||
for (vr::TrackedDeviceIndex_t trackedDevice = 0;
|
||||
trackedDevice < vr::k_unMaxTrackedDeviceCount; trackedDevice++ ) {
|
||||
vr::VRControllerState_t state;
|
||||
|
||||
if (mVRSystem->GetTrackedDeviceClass(trackedDevice)
|
||||
!= vr::TrackedDeviceClass_Controller) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (mVRSystem->GetControllerState(trackedDevice, &state)) {
|
||||
if (state.ulButtonPressed) {
|
||||
// TODO: For Bug 1299929 after landing, convert the button mask to an ID button
|
||||
// NewButtonEvent(1,
|
||||
// 0,
|
||||
// 0,
|
||||
// true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
VRControllerManagerOpenVR::GetControllers(nsTArray<RefPtr<VRControllerHost>>& aControllerResult)
|
||||
{
|
||||
if (!mOpenVRInstalled) {
|
||||
return;
|
||||
}
|
||||
|
||||
aControllerResult.Clear();
|
||||
for (uint32_t i = 0; i < mOpenVRController.Length(); ++i) {
|
||||
aControllerResult.AppendElement(mOpenVRController[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
VRControllerManagerOpenVR::ScanForDevices()
|
||||
{
|
||||
mControllerCount = 0;
|
||||
mOpenVRController.Clear();
|
||||
|
||||
if (!mVRSystem)
|
||||
return;
|
||||
|
||||
// Basically, we would have HMDs in the tracked devices, but we are just interested in the controllers.
|
||||
for ( vr::TrackedDeviceIndex_t trackedDevice = vr::k_unTrackedDeviceIndex_Hmd + 1;
|
||||
trackedDevice < vr::k_unMaxTrackedDeviceCount; ++trackedDevice ) {
|
||||
if (!mVRSystem->IsTrackedDeviceConnected(trackedDevice)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (mVRSystem->GetTrackedDeviceClass(trackedDevice) != vr::TrackedDeviceClass_Controller) {
|
||||
continue;
|
||||
}
|
||||
|
||||
RefPtr<VRControllerOpenVR> openVRController = new VRControllerOpenVR();
|
||||
mOpenVRController.AppendElement(openVRController);
|
||||
|
||||
// Not already present, add it.
|
||||
AddGamepad("OpenVR Gamepad", GamepadMappingType::_empty,
|
||||
kOpenVRControllerAxes, kOpenVRControllerButtons);
|
||||
++mControllerCount;
|
||||
}
|
||||
}
|
|
@ -86,6 +86,43 @@ protected:
|
|||
bool mOpenVRInstalled;
|
||||
};
|
||||
|
||||
namespace impl {
|
||||
|
||||
class VRControllerOpenVR : public VRControllerHost
|
||||
{
|
||||
public:
|
||||
explicit VRControllerOpenVR();
|
||||
|
||||
protected:
|
||||
virtual ~VRControllerOpenVR();
|
||||
};
|
||||
|
||||
} // namespace impl
|
||||
|
||||
class VRControllerManagerOpenVR : public VRControllerManager
|
||||
{
|
||||
public:
|
||||
static already_AddRefed<VRControllerManagerOpenVR> Create();
|
||||
|
||||
virtual bool Init() override;
|
||||
virtual void Destroy() override;
|
||||
virtual void HandleInput() override;
|
||||
virtual void GetControllers(nsTArray<RefPtr<VRControllerHost>>&
|
||||
aControllerResult) override;
|
||||
virtual void ScanForDevices() override;
|
||||
|
||||
private:
|
||||
VRControllerManagerOpenVR();
|
||||
~VRControllerManagerOpenVR();
|
||||
|
||||
bool mOpenVRInstalled;
|
||||
nsTArray<RefPtr<impl::VRControllerOpenVR>> mOpenVRController;
|
||||
vr::IVRSystem *mVRSystem;
|
||||
|
||||
const uint32_t kOpenVRControllerButtons = 8;
|
||||
const uint32_t kOpenVRControllerAxes = 5;
|
||||
};
|
||||
|
||||
} // namespace gfx
|
||||
} // namespace mozilla
|
||||
|
||||
|
|
|
@ -10,6 +10,7 @@ include protocol PLayer;
|
|||
include protocol PTexture;
|
||||
include protocol PVRLayer;
|
||||
include LayersMessages;
|
||||
include GamepadEventTypes;
|
||||
|
||||
include "VRMessageUtils.h";
|
||||
|
||||
|
@ -17,6 +18,7 @@ using struct mozilla::gfx::VRFieldOfView from "gfxVR.h";
|
|||
using struct mozilla::gfx::VRDisplayInfo from "gfxVR.h";
|
||||
using struct mozilla::gfx::VRSensorUpdate from "gfxVR.h";
|
||||
using struct mozilla::gfx::VRHMDSensorState from "gfxVR.h";
|
||||
using struct mozilla::gfx::VRControllerInfo from "gfxVR.h";
|
||||
using mozilla::layers::LayersBackend from "mozilla/layers/LayersTypes.h";
|
||||
using mozilla::layers::TextureFlags from "mozilla/layers/CompositorTypes.h";
|
||||
|
||||
|
@ -56,6 +58,12 @@ parent:
|
|||
sync GetImmediateSensorState(uint32_t aDisplayID) returns(VRHMDSensorState aState);
|
||||
sync SetHaveEventListener(bool aHaveEventListener);
|
||||
|
||||
async ControllerListenerAdded();
|
||||
async ControllerListenerRemoved();
|
||||
// GetControllers synchronously returns the VR controllers that have already been
|
||||
// enumerated by RefreshVRControllers() but does not enumerate new ones.
|
||||
sync GetControllers() returns(VRControllerInfo[] aControllerInfo);
|
||||
|
||||
child:
|
||||
|
||||
async ParentAsyncMessages(AsyncParentMessageData[] aMessages);
|
||||
|
@ -68,6 +76,7 @@ child:
|
|||
|
||||
async NotifyVSync();
|
||||
async NotifyVRVSync(uint32_t aDisplayID);
|
||||
async GamepadUpdate(GamepadChangeEvent aGamepadEvent);
|
||||
|
||||
async __delete__();
|
||||
|
||||
|
|
|
@ -8,12 +8,14 @@
|
|||
#include "VRManagerChild.h"
|
||||
#include "VRManagerParent.h"
|
||||
#include "VRDisplayClient.h"
|
||||
#include "nsGlobalWindow.h"
|
||||
#include "mozilla/StaticPtr.h"
|
||||
#include "mozilla/layers/CompositorThread.h" // for CompositorThread
|
||||
#include "mozilla/dom/Navigator.h"
|
||||
#include "mozilla/dom/VREventObserver.h"
|
||||
#include "mozilla/dom/WindowBinding.h" // for FrameRequestCallback
|
||||
#include "mozilla/dom/ContentChild.h"
|
||||
#include "mozilla/dom/GamepadManager.h"
|
||||
#include "mozilla/layers/TextureClient.h"
|
||||
#include "nsContentUtils.h"
|
||||
|
||||
|
@ -37,6 +39,7 @@ void ReleaseVRManagerParentSingleton() {
|
|||
VRManagerChild::VRManagerChild()
|
||||
: TextureForwarder()
|
||||
, mDisplaysInitialized(false)
|
||||
, mGamepadManager(nullptr)
|
||||
, mInputFrameID(-1)
|
||||
, mMessageLoop(MessageLoop::current())
|
||||
, mFrameRequestCallbackCounter(0)
|
||||
|
@ -480,6 +483,19 @@ VRManagerChild::RecvNotifyVRVSync(const uint32_t& aDisplayID)
|
|||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
VRManagerChild::RecvGamepadUpdate(const GamepadChangeEvent& aGamepadEvent)
|
||||
{
|
||||
// VRManagerChild could be at other processes, but GamepadManager
|
||||
// only exists at the content process or the parent process
|
||||
// in non-e10s mode.
|
||||
if (mGamepadManager) {
|
||||
mGamepadManager->Update(aGamepadEvent);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
VRManagerChild::RunFrameRequestCallbacks()
|
||||
{
|
||||
|
@ -573,5 +589,13 @@ VRManagerChild::FatalError(const char* const aName, const char* const aMsg) cons
|
|||
dom::ContentChild::FatalErrorIfNotUsingGPUProcess(aName, aMsg, OtherPid());
|
||||
}
|
||||
|
||||
void
|
||||
VRManagerChild::SetGamepadManager(dom::GamepadManager* aGamepadManager)
|
||||
{
|
||||
MOZ_ASSERT(aGamepadManager);
|
||||
|
||||
mGamepadManager = aGamepadManager;
|
||||
}
|
||||
|
||||
} // namespace gfx
|
||||
} // namespace mozilla
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
class GamepadManager;
|
||||
class Navigator;
|
||||
class VRDisplay;
|
||||
class VREventObserver;
|
||||
|
@ -77,6 +78,9 @@ public:
|
|||
int32_t *aHandle);
|
||||
void CancelFrameRequestCallback(int32_t aHandle);
|
||||
void RunFrameRequestCallbacks();
|
||||
// GamepadManager has to be set by the content side to make sure we are using
|
||||
// the same singleton GamepadManager from the same process.
|
||||
void SetGamepadManager(dom::GamepadManager* aGamepadManager);
|
||||
|
||||
void UpdateDisplayInfo(nsTArray<VRDisplayInfo>& aDisplayUpdates);
|
||||
void FireDOMVRDisplayConnectEvent();
|
||||
|
@ -114,7 +118,7 @@ protected:
|
|||
|
||||
virtual bool RecvNotifyVSync() override;
|
||||
virtual bool RecvNotifyVRVSync(const uint32_t& aDisplayID) override;
|
||||
|
||||
virtual bool RecvGamepadUpdate(const GamepadChangeEvent& aGamepadEvent) override;
|
||||
|
||||
// ShmemAllocator
|
||||
|
||||
|
@ -151,6 +155,7 @@ private:
|
|||
nsTArray<RefPtr<VRDisplayClient> > mDisplays;
|
||||
bool mDisplaysInitialized;
|
||||
nsTArray<dom::Navigator*> mNavigatorCallbacks;
|
||||
dom::GamepadManager* mGamepadManager;
|
||||
|
||||
int32_t mInputFrameID;
|
||||
|
||||
|
|
|
@ -291,5 +291,29 @@ VRManagerParent::RecvSetHaveEventListener(const bool& aHaveEventListener)
|
|||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
VRManagerParent::RecvControllerListenerAdded()
|
||||
{
|
||||
VRManager* vm = VRManager::Get();
|
||||
// Ask the connected gamepads to be added to GamepadManager
|
||||
vm->ScanForDevices();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
VRManagerParent::RecvControllerListenerRemoved()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
VRManagerParent::RecvGetControllers(nsTArray<VRControllerInfo> *aControllers)
|
||||
{
|
||||
VRManager* vm = VRManager::Get();
|
||||
vm->GetVRControllerInfo(*aControllers);
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace gfx
|
||||
} // namespace mozilla
|
||||
|
|
|
@ -84,6 +84,9 @@ protected:
|
|||
virtual bool RecvGetSensorState(const uint32_t& aDisplayID, VRHMDSensorState* aState) override;
|
||||
virtual bool RecvGetImmediateSensorState(const uint32_t& aDisplayID, VRHMDSensorState* aState) override;
|
||||
virtual bool RecvSetHaveEventListener(const bool& aHaveEventListener) override;
|
||||
virtual bool RecvControllerListenerAdded() override;
|
||||
virtual bool RecvControllerListenerRemoved() override;
|
||||
virtual bool RecvGetControllers(nsTArray<VRControllerInfo> *aControllers) override;
|
||||
|
||||
private:
|
||||
void RegisterWithManager();
|
||||
|
|
|
@ -16,10 +16,10 @@
|
|||
namespace IPC {
|
||||
|
||||
template<>
|
||||
struct ParamTraits<mozilla::gfx::VRDisplayType> :
|
||||
public ContiguousEnumSerializer<mozilla::gfx::VRDisplayType,
|
||||
mozilla::gfx::VRDisplayType(0),
|
||||
mozilla::gfx::VRDisplayType(mozilla::gfx::VRDisplayType::NumVRDisplayTypes)> {};
|
||||
struct ParamTraits<mozilla::gfx::VRDeviceType> :
|
||||
public ContiguousEnumSerializer<mozilla::gfx::VRDeviceType,
|
||||
mozilla::gfx::VRDeviceType(0),
|
||||
mozilla::gfx::VRDeviceType(mozilla::gfx::VRDeviceType::NumVRDeviceTypes)> {};
|
||||
|
||||
template<>
|
||||
struct ParamTraits<mozilla::gfx::VRDisplayCapabilityFlags> :
|
||||
|
@ -159,6 +159,35 @@ struct ParamTraits<mozilla::gfx::VRFieldOfView>
|
|||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct ParamTraits<mozilla::gfx::VRControllerInfo>
|
||||
{
|
||||
typedef mozilla::gfx::VRControllerInfo paramType;
|
||||
|
||||
static void Write(Message* aMsg, const paramType& aParam)
|
||||
{
|
||||
WriteParam(aMsg, aParam.mType);
|
||||
WriteParam(aMsg, aParam.mControllerID);
|
||||
WriteParam(aMsg, aParam.mControllerName);
|
||||
WriteParam(aMsg, aParam.mMappingType);
|
||||
WriteParam(aMsg, aParam.mNumButtons);
|
||||
WriteParam(aMsg, aParam.mNumAxes);
|
||||
}
|
||||
|
||||
static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
|
||||
{
|
||||
if (!ReadParam(aMsg, aIter, &(aResult->mType)) ||
|
||||
!ReadParam(aMsg, aIter, &(aResult->mControllerID)) ||
|
||||
!ReadParam(aMsg, aIter, &(aResult->mControllerName)) ||
|
||||
!ReadParam(aMsg, aIter, &(aResult->mMappingType)) ||
|
||||
!ReadParam(aMsg, aIter, &(aResult->mNumButtons)) ||
|
||||
!ReadParam(aMsg, aIter, &(aResult->mNumAxes))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
} // namespace IPC
|
||||
|
||||
#endif // mozilla_gfx_vr_VRMessageUtils_h
|
||||
|
|
|
@ -16,6 +16,7 @@ EXPORTS += [
|
|||
]
|
||||
|
||||
LOCAL_INCLUDES += [
|
||||
'/dom/base',
|
||||
'/gfx/layers/d3d11',
|
||||
'/gfx/thebes',
|
||||
]
|
||||
|
|
|
@ -66,8 +66,10 @@ public class ActivityStream {
|
|||
*
|
||||
* This method implements the proposal from this desktop AS issue:
|
||||
* https://github.com/mozilla/activity-stream/issues/1311
|
||||
*
|
||||
* @param usePath Use the path of the URL to extract a label (if suitable)
|
||||
*/
|
||||
public static String extractLabel(String url) {
|
||||
public static String extractLabel(String url, boolean usePath) {
|
||||
if (TextUtils.isEmpty(url)) {
|
||||
return "";
|
||||
}
|
||||
|
@ -75,21 +77,23 @@ public class ActivityStream {
|
|||
final Uri uri = Uri.parse(url);
|
||||
|
||||
// Use last path segment if suitable
|
||||
final String segment = uri.getLastPathSegment();
|
||||
if (!TextUtils.isEmpty(segment)
|
||||
&& !UNDESIRED_LABELS.contains(segment)
|
||||
&& !segment.matches("^[0-9]+$")) {
|
||||
if (usePath) {
|
||||
final String segment = uri.getLastPathSegment();
|
||||
if (!TextUtils.isEmpty(segment)
|
||||
&& !UNDESIRED_LABELS.contains(segment)
|
||||
&& !segment.matches("^[0-9]+$")) {
|
||||
|
||||
boolean hasUndesiredPrefix = false;
|
||||
for (int i = 0; i < UNDESIRED_LABEL_PREFIXES.size(); i++) {
|
||||
if (segment.startsWith(UNDESIRED_LABEL_PREFIXES.get(i))) {
|
||||
hasUndesiredPrefix = true;
|
||||
break;
|
||||
boolean hasUndesiredPrefix = false;
|
||||
for (int i = 0; i < UNDESIRED_LABEL_PREFIXES.size(); i++) {
|
||||
if (segment.startsWith(UNDESIRED_LABEL_PREFIXES.get(i))) {
|
||||
hasUndesiredPrefix = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!hasUndesiredPrefix) {
|
||||
return segment;
|
||||
if (!hasUndesiredPrefix) {
|
||||
return segment;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -5,23 +5,26 @@
|
|||
package org.mozilla.gecko.home.activitystream;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
import android.database.Cursor;
|
||||
import android.os.Bundle;
|
||||
import android.support.v4.app.LoaderManager;
|
||||
import android.support.v4.content.ContextCompat;
|
||||
import android.support.v4.content.Loader;
|
||||
import android.support.v4.graphics.ColorUtils;
|
||||
import android.support.v7.widget.LinearLayoutManager;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.DisplayMetrics;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
import android.util.TypedValue;
|
||||
import android.widget.FrameLayout;
|
||||
|
||||
import org.mozilla.gecko.GeckoProfile;
|
||||
import org.mozilla.gecko.R;
|
||||
import org.mozilla.gecko.db.BrowserDB;
|
||||
import org.mozilla.gecko.home.HomePager;
|
||||
import org.mozilla.gecko.home.SimpleCursorLoader;
|
||||
import org.mozilla.gecko.home.activitystream.topsites.TopSitesPagerAdapter;
|
||||
import org.mozilla.gecko.util.ContextUtils;
|
||||
import org.mozilla.gecko.widget.RecyclerViewClickSupport;
|
||||
|
||||
public class ActivityStream extends FrameLayout {
|
||||
|
@ -30,9 +33,18 @@ public class ActivityStream extends FrameLayout {
|
|||
private static final int LOADER_ID_HIGHLIGHTS = 0;
|
||||
private static final int LOADER_ID_TOPSITES = 1;
|
||||
|
||||
private static final int MINIMUM_TILES = 4;
|
||||
private static final int MAXIMUM_TILES = 6;
|
||||
|
||||
private int desiredTileWidth;
|
||||
private int desiredTilesHeight;
|
||||
private int tileMargin;
|
||||
|
||||
public ActivityStream(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
|
||||
setBackgroundColor(ContextCompat.getColor(context, R.color.about_page_header_grey));
|
||||
|
||||
inflate(context, R.layout.as_content, this);
|
||||
|
||||
adapter = new StreamRecyclerAdapter();
|
||||
|
@ -45,6 +57,11 @@ public class ActivityStream extends FrameLayout {
|
|||
|
||||
RecyclerViewClickSupport.addTo(rv)
|
||||
.setOnItemClickListener(adapter);
|
||||
|
||||
final Resources resources = getResources();
|
||||
desiredTileWidth = resources.getDimensionPixelSize(R.dimen.activity_stream_desired_tile_width);
|
||||
desiredTilesHeight = resources.getDimensionPixelSize(R.dimen.activity_stream_desired_tile_height);
|
||||
tileMargin = resources.getDimensionPixelSize(R.dimen.activity_stream_base_margin);
|
||||
}
|
||||
|
||||
void setOnUrlOpenListener(HomePager.OnUrlOpenListener listener) {
|
||||
|
@ -63,6 +80,36 @@ public class ActivityStream extends FrameLayout {
|
|||
adapter.swapTopSitesCursor(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
|
||||
super.onSizeChanged(w, h, oldw, oldh);
|
||||
|
||||
int tiles = (w - tileMargin) / (desiredTileWidth + tileMargin);
|
||||
|
||||
if (tiles < MINIMUM_TILES) {
|
||||
tiles = MINIMUM_TILES;
|
||||
|
||||
setPadding(0, 0, 0, 0);
|
||||
} else if (tiles > MAXIMUM_TILES) {
|
||||
tiles = MAXIMUM_TILES;
|
||||
|
||||
// Use the remaining space as padding
|
||||
int needed = tiles * (desiredTileWidth + tileMargin) + tileMargin;
|
||||
int padding = (w - needed) / 2;
|
||||
w = needed;
|
||||
|
||||
setPadding(padding, 0, padding, 0);
|
||||
} else {
|
||||
setPadding(0, 0, 0, 0);
|
||||
}
|
||||
|
||||
final float ratio = (float) desiredTilesHeight / (float) desiredTileWidth;
|
||||
final int tilesWidth = (w - (tiles * tileMargin) - tileMargin) / tiles;
|
||||
final int tilesHeight = (int) (ratio * tilesWidth);
|
||||
|
||||
adapter.setTileSize(tiles, tilesWidth, tilesHeight);
|
||||
}
|
||||
|
||||
private class CursorLoaderCallbacks implements LoaderManager.LoaderCallbacks<Cursor> {
|
||||
@Override
|
||||
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
|
||||
|
@ -71,7 +118,7 @@ public class ActivityStream extends FrameLayout {
|
|||
return BrowserDB.from(context).getHighlights(context, 10);
|
||||
} else if (id == LOADER_ID_TOPSITES) {
|
||||
return BrowserDB.from(context).getActivityStreamTopSites(
|
||||
context, TopSitesPagerAdapter.TOTAL_ITEMS);
|
||||
context, TopSitesPagerAdapter.PAGES * MAXIMUM_TILES);
|
||||
} else {
|
||||
throw new IllegalArgumentException("Can't handle loader id " + id);
|
||||
}
|
||||
|
|
|
@ -4,11 +4,18 @@
|
|||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
package org.mozilla.gecko.home.activitystream;
|
||||
|
||||
import android.content.res.Resources;
|
||||
import android.database.Cursor;
|
||||
import android.graphics.Color;
|
||||
import android.support.v4.view.ViewPager;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
import android.text.TextUtils;
|
||||
import android.text.format.DateUtils;
|
||||
import android.util.DisplayMetrics;
|
||||
import android.util.TypedValue;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import org.mozilla.gecko.R;
|
||||
|
@ -19,21 +26,21 @@ import org.mozilla.gecko.home.activitystream.topsites.TopSitesPagerAdapter;
|
|||
import org.mozilla.gecko.icons.IconCallback;
|
||||
import org.mozilla.gecko.icons.IconResponse;
|
||||
import org.mozilla.gecko.icons.Icons;
|
||||
import org.mozilla.gecko.util.DrawableUtil;
|
||||
import org.mozilla.gecko.widget.FaviconView;
|
||||
|
||||
import java.util.concurrent.Future;
|
||||
|
||||
import static org.mozilla.gecko.activitystream.ActivityStream.extractLabel;
|
||||
|
||||
public abstract class StreamItem extends RecyclerView.ViewHolder {
|
||||
public StreamItem(View itemView) {
|
||||
super(itemView);
|
||||
}
|
||||
|
||||
public void bind(Cursor cursor) {
|
||||
throw new IllegalStateException("Cannot bind " + this.getClass().getSimpleName());
|
||||
}
|
||||
|
||||
public static class TopPanel extends StreamItem {
|
||||
public static final int LAYOUT_ID = R.layout.activity_stream_main_toppanel;
|
||||
|
||||
private final ViewPager topSitesPager;
|
||||
|
||||
public TopPanel(View itemView, HomePager.OnUrlOpenListener onUrlOpenListener) {
|
||||
|
@ -46,17 +53,18 @@ public abstract class StreamItem extends RecyclerView.ViewHolder {
|
|||
indicator.setViewPager(topSitesPager);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void bind(Cursor cursor) {
|
||||
((TopSitesPagerAdapter) topSitesPager.getAdapter()).swapCursor(cursor);
|
||||
}
|
||||
}
|
||||
public void bind(Cursor cursor, int tiles, int tilesWidth, int tilesHeight) {
|
||||
final TopSitesPagerAdapter adapter = (TopSitesPagerAdapter) topSitesPager.getAdapter();
|
||||
adapter.setTilesSize(tiles, tilesWidth, tilesHeight);
|
||||
adapter.swapCursor(cursor);
|
||||
|
||||
public static class BottomPanel extends StreamItem {
|
||||
public static final int LAYOUT_ID = R.layout.activity_stream_main_bottompanel;
|
||||
final Resources resources = itemView.getResources();
|
||||
final int tilesMargin = resources.getDimensionPixelSize(R.dimen.activity_stream_base_margin);
|
||||
final int textHeight = resources.getDimensionPixelSize(R.dimen.activity_stream_top_sites_text_height);
|
||||
|
||||
public BottomPanel(View itemView) {
|
||||
super(itemView);
|
||||
ViewGroup.LayoutParams layoutParams = topSitesPager.getLayoutParams();
|
||||
layoutParams.height = tilesHeight + tilesMargin + textHeight;
|
||||
topSitesPager.setLayoutParams(layoutParams);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -67,19 +75,29 @@ public abstract class StreamItem extends RecyclerView.ViewHolder {
|
|||
final TextView vLabel;
|
||||
final TextView vTimeSince;
|
||||
final TextView vSourceView;
|
||||
final TextView vPageView;
|
||||
|
||||
private Future<IconResponse> ongoingIconLoad;
|
||||
private int tilesMargin;
|
||||
|
||||
public HighlightItem(View itemView) {
|
||||
super(itemView);
|
||||
|
||||
tilesMargin = itemView.getResources().getDimensionPixelSize(R.dimen.activity_stream_base_margin);
|
||||
|
||||
vLabel = (TextView) itemView.findViewById(R.id.card_history_label);
|
||||
vTimeSince = (TextView) itemView.findViewById(R.id.card_history_time_since);
|
||||
vIconView = (FaviconView) itemView.findViewById(R.id.icon);
|
||||
vSourceView = (TextView) itemView.findViewById(R.id.card_history_source);
|
||||
vPageView = (TextView) itemView.findViewById(R.id.page);
|
||||
|
||||
ImageView menuButton = (ImageView) itemView.findViewById(R.id.menu);
|
||||
|
||||
menuButton.setImageDrawable(
|
||||
DrawableUtil.tintDrawable(menuButton.getContext(), R.drawable.menu, Color.LTGRAY));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void bind(Cursor cursor) {
|
||||
public void bind(Cursor cursor, int tilesWidth, int tilesHeight) {
|
||||
final long time = cursor.getLong(cursor.getColumnIndexOrThrow(BrowserContract.Highlights.DATE));
|
||||
final String ago = DateUtils.getRelativeTimeSpanString(time, System.currentTimeMillis(), DateUtils.MINUTE_IN_MILLIS, 0).toString();
|
||||
final String url = cursor.getString(cursor.getColumnIndexOrThrow(BrowserContract.Combined.URL));
|
||||
|
@ -87,7 +105,13 @@ public abstract class StreamItem extends RecyclerView.ViewHolder {
|
|||
vLabel.setText(cursor.getString(cursor.getColumnIndexOrThrow(BrowserContract.History.TITLE)));
|
||||
vTimeSince.setText(ago);
|
||||
|
||||
ViewGroup.LayoutParams layoutParams = vIconView.getLayoutParams();
|
||||
layoutParams.width = tilesWidth - tilesMargin;
|
||||
layoutParams.height = tilesHeight;
|
||||
vIconView.setLayoutParams(layoutParams);
|
||||
|
||||
updateSource(cursor);
|
||||
updatePage(url);
|
||||
|
||||
if (ongoingIconLoad != null) {
|
||||
ongoingIconLoad.cancel(true);
|
||||
|
@ -117,6 +141,16 @@ public abstract class StreamItem extends RecyclerView.ViewHolder {
|
|||
vSourceView.setText(vSourceView.getText());
|
||||
}
|
||||
|
||||
private void updatePage(String url) {
|
||||
final String label = extractLabel(url, false);
|
||||
|
||||
if (!TextUtils.isEmpty(label)) {
|
||||
vPageView.setText(label);
|
||||
} else {
|
||||
vPageView.setText(url);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onIconResponse(IconResponse response) {
|
||||
vIconView.updateImage(response);
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
* 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/. */
|
||||
|
||||
package org.mozilla.gecko.home.activitystream;
|
||||
|
||||
import android.database.Cursor;
|
||||
|
@ -12,7 +13,6 @@ import android.view.ViewGroup;
|
|||
|
||||
import org.mozilla.gecko.db.BrowserContract;
|
||||
import org.mozilla.gecko.home.HomePager;
|
||||
import org.mozilla.gecko.home.activitystream.StreamItem.BottomPanel;
|
||||
import org.mozilla.gecko.home.activitystream.StreamItem.HighlightItem;
|
||||
import org.mozilla.gecko.home.activitystream.StreamItem.TopPanel;
|
||||
import org.mozilla.gecko.widget.RecyclerViewClickSupport;
|
||||
|
@ -25,16 +25,26 @@ public class StreamRecyclerAdapter extends RecyclerView.Adapter<StreamItem> impl
|
|||
|
||||
private HomePager.OnUrlOpenListener onUrlOpenListener;
|
||||
|
||||
private int tiles;
|
||||
private int tilesWidth;
|
||||
private int tilesHeight;
|
||||
|
||||
void setOnUrlOpenListener(HomePager.OnUrlOpenListener onUrlOpenListener) {
|
||||
this.onUrlOpenListener = onUrlOpenListener;
|
||||
}
|
||||
|
||||
public void setTileSize(int tiles, int tilesWidth, int tilesHeight) {
|
||||
this.tilesWidth = tilesWidth;
|
||||
this.tilesHeight = tilesHeight;
|
||||
this.tiles = tiles;
|
||||
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemViewType(int position) {
|
||||
if (position == 0) {
|
||||
return TopPanel.LAYOUT_ID;
|
||||
} else if (position == getItemCount() - 1) {
|
||||
return BottomPanel.LAYOUT_ID;
|
||||
} else {
|
||||
return HighlightItem.LAYOUT_ID;
|
||||
}
|
||||
|
@ -46,8 +56,6 @@ public class StreamRecyclerAdapter extends RecyclerView.Adapter<StreamItem> impl
|
|||
|
||||
if (type == TopPanel.LAYOUT_ID) {
|
||||
return new TopPanel(inflater.inflate(type, parent, false), onUrlOpenListener);
|
||||
} else if (type == BottomPanel.LAYOUT_ID) {
|
||||
return new BottomPanel(inflater.inflate(type, parent, false));
|
||||
} else if (type == HighlightItem.LAYOUT_ID) {
|
||||
return new HighlightItem(inflater.inflate(type, parent, false));
|
||||
} else {
|
||||
|
@ -56,8 +64,7 @@ public class StreamRecyclerAdapter extends RecyclerView.Adapter<StreamItem> impl
|
|||
}
|
||||
|
||||
private int translatePositionToCursor(int position) {
|
||||
if (position == 0 ||
|
||||
position == getItemCount() - 1) {
|
||||
if (position == 0) {
|
||||
throw new IllegalArgumentException("Requested cursor position for invalid item");
|
||||
}
|
||||
|
||||
|
@ -73,9 +80,9 @@ public class StreamRecyclerAdapter extends RecyclerView.Adapter<StreamItem> impl
|
|||
final int cursorPosition = translatePositionToCursor(position);
|
||||
|
||||
highlightsCursor.moveToPosition(cursorPosition);
|
||||
holder.bind(highlightsCursor);
|
||||
((HighlightItem) holder).bind(highlightsCursor, tilesWidth, tilesHeight);
|
||||
} else if (type == TopPanel.LAYOUT_ID) {
|
||||
holder.bind(topSitesCursor);
|
||||
((TopPanel) holder).bind(topSitesCursor, tiles, tilesWidth, tilesHeight);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -104,7 +111,7 @@ public class StreamRecyclerAdapter extends RecyclerView.Adapter<StreamItem> impl
|
|||
highlightsCount = 0;
|
||||
}
|
||||
|
||||
return 2 + highlightsCount;
|
||||
return highlightsCount + 1;
|
||||
}
|
||||
|
||||
public void swapHighlightsCursor(Cursor cursor) {
|
||||
|
|
|
@ -4,17 +4,18 @@
|
|||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
package org.mozilla.gecko.home.activitystream.topsites;
|
||||
|
||||
import android.database.Cursor;
|
||||
import android.support.v7.widget.CardView;
|
||||
import android.graphics.Color;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
import android.view.View;
|
||||
import android.widget.FrameLayout;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import org.mozilla.gecko.R;
|
||||
import org.mozilla.gecko.db.BrowserContract;
|
||||
import org.mozilla.gecko.activitystream.ActivityStream;
|
||||
import org.mozilla.gecko.icons.IconCallback;
|
||||
import org.mozilla.gecko.icons.IconResponse;
|
||||
import org.mozilla.gecko.icons.Icons;
|
||||
import org.mozilla.gecko.util.DrawableUtil;
|
||||
import org.mozilla.gecko.widget.FaviconView;
|
||||
|
||||
import java.util.concurrent.Future;
|
||||
|
@ -23,31 +24,28 @@ class TopSitesCard extends RecyclerView.ViewHolder implements IconCallback {
|
|||
private final FaviconView faviconView;
|
||||
|
||||
private final TextView title;
|
||||
private final View menuButton;
|
||||
private final ImageView menuButton;
|
||||
private Future<IconResponse> ongoingIconLoad;
|
||||
|
||||
private String url;
|
||||
|
||||
public TopSitesCard(CardView card) {
|
||||
public TopSitesCard(FrameLayout card) {
|
||||
super(card);
|
||||
|
||||
faviconView = (FaviconView) card.findViewById(R.id.favicon);
|
||||
|
||||
title = (TextView) card.findViewById(R.id.title);
|
||||
menuButton = card.findViewById(R.id.menu);
|
||||
menuButton = (ImageView) card.findViewById(R.id.menu);
|
||||
}
|
||||
|
||||
void bind(Cursor cursor) {
|
||||
this.url = cursor.getString(cursor.getColumnIndexOrThrow(BrowserContract.Combined.URL));
|
||||
|
||||
title.setText(cursor.getString(cursor.getColumnIndexOrThrow(BrowserContract.Combined.TITLE)));
|
||||
void bind(TopSitesPageAdapter.TopSite topSite) {
|
||||
final String label = ActivityStream.extractLabel(topSite.url, true);
|
||||
title.setText(label);
|
||||
|
||||
if (ongoingIconLoad != null) {
|
||||
ongoingIconLoad.cancel(true);
|
||||
}
|
||||
|
||||
ongoingIconLoad = Icons.with(itemView.getContext())
|
||||
.pageUrl(url)
|
||||
.pageUrl(topSite.url)
|
||||
.skipNetwork()
|
||||
.build()
|
||||
.execute(this);
|
||||
|
@ -56,5 +54,10 @@ class TopSitesCard extends RecyclerView.ViewHolder implements IconCallback {
|
|||
@Override
|
||||
public void onIconResponse(IconResponse response) {
|
||||
faviconView.updateImage(response);
|
||||
|
||||
final int tintColor = !response.hasColor() || response.getColor() == Color.WHITE ? Color.LTGRAY : Color.WHITE;
|
||||
|
||||
menuButton.setImageDrawable(
|
||||
DrawableUtil.tintDrawable(menuButton.getContext(), R.drawable.menu, tintColor));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,12 +23,16 @@ public class TopSitesPage
|
|||
@Nullable AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
|
||||
setLayoutManager(new GridLayoutManager(context, TopSitesPagerAdapter.GRID_WIDTH));
|
||||
setLayoutManager(new GridLayoutManager(context, 1));
|
||||
|
||||
RecyclerViewClickSupport.addTo(this)
|
||||
.setOnItemClickListener(this);
|
||||
}
|
||||
|
||||
public void setTiles(int tiles) {
|
||||
setLayoutManager(new GridLayoutManager(getContext(), tiles));
|
||||
}
|
||||
|
||||
private HomePager.OnUrlOpenListener onUrlOpenListener = null;
|
||||
|
||||
public TopSitesPageAdapter getAdapter() {
|
||||
|
|
|
@ -4,52 +4,51 @@
|
|||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
package org.mozilla.gecko.home.activitystream.topsites;
|
||||
|
||||
import android.content.Context;
|
||||
import android.database.Cursor;
|
||||
import android.database.CursorWrapper;
|
||||
import android.support.annotation.UiThread;
|
||||
import android.support.v7.widget.CardView;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
import android.util.Log;
|
||||
import android.util.TypedValue;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.FrameLayout;
|
||||
|
||||
import org.mozilla.gecko.R;
|
||||
import org.mozilla.gecko.db.BrowserContract;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class TopSitesPageAdapter extends RecyclerView.Adapter<TopSitesCard> {
|
||||
static final class TopSite {
|
||||
public final long id;
|
||||
public final String url;
|
||||
|
||||
/**
|
||||
* Cursor wrapper that handles the offsets and limits that we expect.
|
||||
* This allows most of our code to completely ignore the fact that we're only touching part
|
||||
* of the cursor.
|
||||
*/
|
||||
private static final class SubsetCursor extends CursorWrapper {
|
||||
private final int start;
|
||||
private final int count;
|
||||
|
||||
public SubsetCursor(Cursor cursor, int start, int maxCount) {
|
||||
super(cursor);
|
||||
|
||||
this.start = start;
|
||||
|
||||
if (start + maxCount < cursor.getCount()) {
|
||||
count = maxCount;
|
||||
} else {
|
||||
count = cursor.getCount() - start;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean moveToPosition(int position) {
|
||||
return super.moveToPosition(position + start);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCount() {
|
||||
return count;
|
||||
TopSite(long id, String url) {
|
||||
this.id = id;
|
||||
this.url = url;
|
||||
}
|
||||
}
|
||||
|
||||
private Cursor cursor;
|
||||
private List<TopSite> topSites;
|
||||
private int tiles;
|
||||
private int tilesWidth;
|
||||
private int tilesHeight;
|
||||
private int textHeight;
|
||||
|
||||
public TopSitesPageAdapter(Context context, int tiles, int tilesWidth, int tilesHeight) {
|
||||
setHasStableIds(true);
|
||||
|
||||
this.topSites = new ArrayList<>();
|
||||
this.tiles = tiles;
|
||||
this.tilesWidth = tilesWidth;
|
||||
this.tilesHeight = tilesHeight;
|
||||
this.textHeight = context.getResources().getDimensionPixelSize(R.dimen.activity_stream_top_sites_text_height);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -58,14 +57,21 @@ public class TopSitesPageAdapter extends RecyclerView.Adapter<TopSitesCard> {
|
|||
* 3 items will be displayed by this adapter.
|
||||
*/
|
||||
public void swapCursor(Cursor cursor, int startIndex) {
|
||||
if (cursor != null) {
|
||||
if (startIndex >= cursor.getCount()) {
|
||||
throw new IllegalArgumentException("startIndex must be within Cursor range");
|
||||
}
|
||||
topSites.clear();
|
||||
|
||||
this.cursor = new SubsetCursor(cursor, startIndex, TopSitesPagerAdapter.ITEMS_PER_PAGE);
|
||||
} else {
|
||||
this.cursor = null;
|
||||
if (cursor == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i = 0; i < tiles; i++) {
|
||||
cursor.moveToPosition(startIndex + i);
|
||||
|
||||
// The Combined View only contains pages that have been visited at least once, i.e. any
|
||||
// page in the TopSites query will contain a HISTORY_ID. _ID however will be 0 for all rows.
|
||||
final long id = cursor.getLong(cursor.getColumnIndexOrThrow(BrowserContract.Combined.HISTORY_ID));
|
||||
final String url = cursor.getString(cursor.getColumnIndexOrThrow(BrowserContract.Combined.URL));
|
||||
|
||||
topSites.add(new TopSite(id, url));
|
||||
}
|
||||
|
||||
notifyDataSetChanged();
|
||||
|
@ -73,46 +79,37 @@ public class TopSitesPageAdapter extends RecyclerView.Adapter<TopSitesCard> {
|
|||
|
||||
@Override
|
||||
public void onBindViewHolder(TopSitesCard holder, int position) {
|
||||
cursor.moveToPosition(position);
|
||||
holder.bind(cursor);
|
||||
}
|
||||
|
||||
public TopSitesPageAdapter() {
|
||||
setHasStableIds(true);
|
||||
holder.bind(topSites.get(position));
|
||||
}
|
||||
|
||||
@Override
|
||||
public TopSitesCard onCreateViewHolder(ViewGroup parent, int viewType) {
|
||||
final LayoutInflater inflater = LayoutInflater.from(parent.getContext());
|
||||
|
||||
final CardView card = (CardView) inflater.inflate(R.layout.activity_stream_topsites_card, parent, false);
|
||||
final FrameLayout card = (FrameLayout) inflater.inflate(R.layout.activity_stream_topsites_card, parent, false);
|
||||
final View content = card.findViewById(R.id.content);
|
||||
|
||||
ViewGroup.LayoutParams layoutParams = content.getLayoutParams();
|
||||
layoutParams.width = tilesWidth;
|
||||
layoutParams.height = tilesHeight + textHeight;
|
||||
content.setLayoutParams(layoutParams);
|
||||
|
||||
return new TopSitesCard(card);
|
||||
}
|
||||
|
||||
@UiThread
|
||||
public String getURLForPosition(int position) {
|
||||
cursor.moveToPosition(position);
|
||||
|
||||
return cursor.getString(cursor.getColumnIndexOrThrow(BrowserContract.Combined.URL));
|
||||
return topSites.get(position).url;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
if (cursor != null) {
|
||||
return cursor.getCount();
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
return topSites.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
@UiThread
|
||||
public long getItemId(int position) {
|
||||
cursor.moveToPosition(position);
|
||||
|
||||
// The Combined View only contains pages that have been visited at least once, i.e. any
|
||||
// page in the TopSites query will contain a HISTORY_ID. _ID however will be 0 for all rows.
|
||||
return cursor.getLong(cursor.getColumnIndexOrThrow(BrowserContract.Combined.HISTORY_ID));
|
||||
return topSites.get(position).id;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,14 +21,11 @@ import java.util.LinkedList;
|
|||
* all lower-level Adapters that populate the individual topsite items.
|
||||
*/
|
||||
public class TopSitesPagerAdapter extends PagerAdapter {
|
||||
// Note: because of RecyclerView limitations we need to also adjust the layout height when
|
||||
// GRID_HEIGHT is changed.
|
||||
public static final int GRID_HEIGHT = 1;
|
||||
public static final int GRID_WIDTH = 4;
|
||||
public static final int PAGES = 4;
|
||||
|
||||
public static final int ITEMS_PER_PAGE = GRID_HEIGHT * GRID_WIDTH;
|
||||
public static final int TOTAL_ITEMS = ITEMS_PER_PAGE * PAGES;
|
||||
private int tiles;
|
||||
private int tilesWidth;
|
||||
private int tilesHeight;
|
||||
|
||||
private LinkedList<TopSitesPage> pages = new LinkedList<>();
|
||||
|
||||
|
@ -42,9 +39,15 @@ public class TopSitesPagerAdapter extends PagerAdapter {
|
|||
this.onUrlOpenListener = onUrlOpenListener;
|
||||
}
|
||||
|
||||
public void setTilesSize(int tiles, int tilesWidth, int tilesHeight) {
|
||||
this.tilesWidth = tilesWidth;
|
||||
this.tilesHeight = tilesHeight;
|
||||
this.tiles = tiles;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCount() {
|
||||
return count;
|
||||
return Math.min(count, 4);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -61,30 +64,35 @@ public class TopSitesPagerAdapter extends PagerAdapter {
|
|||
return page;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemPosition(Object object) {
|
||||
return PagerAdapter.POSITION_NONE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroyItem(ViewGroup container, int position, Object object) {
|
||||
container.removeView((View) object);
|
||||
}
|
||||
|
||||
public void swapCursor(Cursor cursor) {
|
||||
final int oldPages = getCount();
|
||||
|
||||
// Divide while rounding up: 0 items = 0 pages, 1-ITEMS_PER_PAGE items = 1 page, etc.
|
||||
if (cursor != null) {
|
||||
count = (cursor.getCount() - 1) / ITEMS_PER_PAGE + 1;
|
||||
count = (cursor.getCount() - 1) / tiles + 1;
|
||||
} else {
|
||||
count = 0;
|
||||
}
|
||||
|
||||
final int pageDelta = count - oldPages;
|
||||
pages.clear();
|
||||
final int pageDelta = count;
|
||||
|
||||
if (pageDelta > 0) {
|
||||
final LayoutInflater inflater = LayoutInflater.from(context);
|
||||
for (int i = 0; i < pageDelta; i++) {
|
||||
final TopSitesPage page = (TopSitesPage) inflater.inflate(R.layout.activity_stream_topsites_page, null, false);
|
||||
|
||||
page.setTiles(tiles);
|
||||
page.setOnUrlOpenListener(onUrlOpenListener);
|
||||
page.setAdapter(new TopSitesPageAdapter());
|
||||
page.setAdapter(new TopSitesPageAdapter(context, tiles, tilesWidth, tilesHeight));
|
||||
pages.add(page);
|
||||
}
|
||||
} else if (pageDelta < 0) {
|
||||
|
@ -103,7 +111,7 @@ public class TopSitesPagerAdapter extends PagerAdapter {
|
|||
int startIndex = 0;
|
||||
for (TopSitesPage page : pages) {
|
||||
page.getAdapter().swapCursor(cursor, startIndex);
|
||||
startIndex += ITEMS_PER_PAGE;
|
||||
startIndex += tiles;
|
||||
}
|
||||
|
||||
notifyDataSetChanged();
|
||||
|
|
|
@ -3,14 +3,15 @@
|
|||
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
|
||||
|
||||
<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:gecko="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="10dp"
|
||||
android:layout_marginEnd="12dp"
|
||||
android:layout_marginLeft="12dp"
|
||||
android:layout_marginRight="12dp"
|
||||
android:layout_marginStart="12dp"
|
||||
android:layout_marginEnd="@dimen/activity_stream_base_margin"
|
||||
android:layout_marginLeft="@dimen/activity_stream_base_margin"
|
||||
android:layout_marginRight="@dimen/activity_stream_base_margin"
|
||||
android:layout_marginStart="@dimen/activity_stream_base_margin"
|
||||
android:layout_marginTop="0dp"
|
||||
android:orientation="vertical">
|
||||
|
||||
|
@ -18,45 +19,87 @@
|
|||
android:layout_width="fill_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="horizontal"
|
||||
android:padding="8dp">
|
||||
android:padding="10dp">
|
||||
|
||||
<org.mozilla.gecko.widget.FaviconView
|
||||
android:id="@+id/icon"
|
||||
android:layout_width="@dimen/favicon_bg"
|
||||
android:layout_height="@dimen/favicon_bg"
|
||||
android:layout_gravity="center"
|
||||
gecko:enableRoundCorners="false"
|
||||
tools:background="@drawable/favicon_globe" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/menu"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="20dp"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:layout_alignParentRight="true"
|
||||
android:layout_alignParentTop="true"
|
||||
android:layout_gravity="right|top"
|
||||
android:padding="2dp"
|
||||
android:layout_marginLeft="@dimen/activity_stream_base_margin"
|
||||
android:layout_marginBottom="@dimen/activity_stream_base_margin"
|
||||
android:src="@drawable/menu" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/page"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
tools:text="twitter"
|
||||
android:textSize="12sp"
|
||||
android:textColor="@color/activity_stream_subtitle"
|
||||
android:layout_toRightOf="@id/icon"
|
||||
android:layout_toEndOf="@id/icon"
|
||||
android:layout_toLeftOf="@id/menu"
|
||||
android:layout_toStartOf="@id/menu"
|
||||
android:paddingLeft="@dimen/activity_stream_base_margin"
|
||||
android:paddingStart="@dimen/activity_stream_base_margin"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/card_history_label"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_toEndOf="@id/icon"
|
||||
android:layout_toRightOf="@id/icon"
|
||||
android:maxLines="2"
|
||||
android:paddingLeft="8dp"
|
||||
android:paddingStart="8dp"
|
||||
android:maxLines="3"
|
||||
android:ellipsize="end"
|
||||
android:paddingLeft="@dimen/activity_stream_base_margin"
|
||||
android:paddingStart="@dimen/activity_stream_base_margin"
|
||||
android:textSize="14sp"
|
||||
android:textStyle="bold"
|
||||
android:textColor="#ff000000"
|
||||
tools:text="Descriptive title of a page..." />
|
||||
android:layout_below="@id/page"
|
||||
android:layout_toLeftOf="@id/menu"
|
||||
android:layout_toStartOf="@id/menu"
|
||||
tools:text="Descriptive title of a page that is veeeeeeery long - maybe even too long?" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:layout_toRightOf="@id/icon"
|
||||
android:paddingLeft="8dp"
|
||||
android:paddingStart="8dp"
|
||||
android:layout_toEndOf="@id/icon"
|
||||
android:layout_alignParentBottom="true"
|
||||
android:paddingLeft="@dimen/activity_stream_base_margin"
|
||||
android:paddingStart="@dimen/activity_stream_base_margin"
|
||||
android:paddingTop="4dp"
|
||||
android:gravity="center_vertical"
|
||||
android:layout_below="@id/card_history_label">
|
||||
|
||||
<ImageView
|
||||
android:layout_width="12dp"
|
||||
android:layout_height="12dp"
|
||||
android:background="#ff8e8e8e" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/card_history_source"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="4dp"
|
||||
android:textSize="12sp"
|
||||
android:layout_weight="1"
|
||||
android:textColor="#ff8e8e8e"
|
||||
android:textColor="@color/activity_stream_subtitle"
|
||||
tools:text="Bookmarked" />
|
||||
|
||||
<TextView
|
||||
|
@ -64,7 +107,7 @@
|
|||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textSize="12sp"
|
||||
android:textColor="#ffd2d2d2"
|
||||
android:textColor="@color/activity_stream_timestamp"
|
||||
tools:text="20m" />
|
||||
|
||||
</LinearLayout>
|
||||
|
|
|
@ -1,7 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:orientation="vertical"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
</LinearLayout>
|
|
@ -7,8 +7,9 @@
|
|||
android:orientation="vertical">
|
||||
|
||||
<android.support.v4.view.ViewPager
|
||||
android:layout_marginTop="10dp"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="123dp"
|
||||
android:layout_height="match_parent"
|
||||
android:id="@+id/topsites_pager"
|
||||
android:layout_alignParentTop="true"
|
||||
android:layout_alignParentLeft="true"
|
||||
|
|
|
@ -1,15 +1,14 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<org.mozilla.gecko.widget.FilledCardView
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:gecko="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="115dp"
|
||||
xmlns:gecko="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_margin="1dp">
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<RelativeLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
android:id="@+id/content"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<org.mozilla.gecko.widget.FaviconView
|
||||
android:id="@+id/favicon"
|
||||
|
@ -19,35 +18,42 @@
|
|||
android:layout_alignParentTop="true"
|
||||
android:layout_centerHorizontal="true"
|
||||
android:layout_gravity="center"
|
||||
tools:background="@drawable/favicon_globe"
|
||||
gecko:enableRoundCorners="false"/>
|
||||
gecko:enableRoundCorners="false"
|
||||
tools:background="@drawable/favicon_globe" />
|
||||
|
||||
<View
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0.5dp"
|
||||
android:layout_below="@id/favicon"
|
||||
android:background="@color/activity_stream_divider" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/title"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentBottom="true"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:layout_alignParentLeft="true"
|
||||
android:layout_alignParentRight="true"
|
||||
android:layout_alignParentStart="true"
|
||||
android:ellipsize="end"
|
||||
android:gravity="center"
|
||||
android:lines="1"
|
||||
android:padding="4dp"
|
||||
android:textSize="12sp"
|
||||
android:textColor="@android:color/black"
|
||||
tools:text="Lorem Ipsum here is a title"
|
||||
android:layout_alignParentRight="true"
|
||||
android:layout_alignParentEnd="true"/>
|
||||
tools:text="Lorem Ipsum here is a title" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/menu_button"
|
||||
android:id="@+id/menu"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="32dp"
|
||||
android:layout_height="28dp"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:layout_alignParentRight="true"
|
||||
android:layout_alignParentTop="true"
|
||||
android:layout_gravity="right|top"
|
||||
android:padding="6dp"
|
||||
android:src="@drawable/menu"
|
||||
android:layout_alignParentTop="true"
|
||||
android:layout_alignParentRight="true"
|
||||
android:layout_alignParentEnd="true"/>
|
||||
android:src="@drawable/menu" />
|
||||
|
||||
</RelativeLayout>
|
||||
</org.mozilla.gecko.widget.FilledCardView>
|
||||
</android.support.v7.widget.CardView>
|
|
@ -1,6 +1,6 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<org.mozilla.gecko.home.activitystream.topsites.TopSitesPage xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:orientation="vertical"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:padding="4dp"/>
|
||||
android:paddingLeft="10dp"/>
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
|
||||
<android.support.v7.widget.RecyclerView
|
||||
android:id="@+id/activity_stream_main_recyclerview"
|
||||
android:background="@color/about_page_header_grey"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"/>
|
||||
</merge>
|
|
@ -140,4 +140,8 @@
|
|||
|
||||
<color name="action_bar_bg_color">@color/toolbar_grey</color>
|
||||
|
||||
<color name="activity_stream_divider">#FFD2D2D2</color>
|
||||
<color name="activity_stream_subtitle">#FF919191</color>
|
||||
<color name="activity_stream_timestamp">#FFD3D3D3</color>
|
||||
|
||||
</resources>
|
||||
|
|
|
@ -216,4 +216,9 @@
|
|||
<item name="firstrun_tab_strip_content_start" type="dimen">15dp</item>
|
||||
|
||||
<item name="notification_media_cover" type="dimen">128dp</item>
|
||||
|
||||
<item name="activity_stream_base_margin" type="dimen">10dp</item>
|
||||
<item name="activity_stream_desired_tile_width" type="dimen">90dp</item>
|
||||
<item name="activity_stream_desired_tile_height" type="dimen">70dp</item>
|
||||
<item name="activity_stream_top_sites_text_height" type="dimen">30dp</item>
|
||||
</resources>
|
||||
|
|
|
@ -18,78 +18,96 @@ public class TestActivityStream {
|
|||
* https://gist.github.com/nchapman/36502ad115e8825d522a66549971a3f0
|
||||
*/
|
||||
@Test
|
||||
public void testExtractLabel() {
|
||||
public void testExtractLabelWithPath() {
|
||||
// Empty values
|
||||
|
||||
assertEquals("", ActivityStream.extractLabel(""));
|
||||
assertEquals("", ActivityStream.extractLabel(null));
|
||||
assertEquals("", ActivityStream.extractLabel("", true));
|
||||
assertEquals("", ActivityStream.extractLabel(null, true));
|
||||
|
||||
// Without path
|
||||
|
||||
assertEquals("news.ycombinator",
|
||||
ActivityStream.extractLabel("https://news.ycombinator.com/"));
|
||||
ActivityStream.extractLabel("https://news.ycombinator.com/", true));
|
||||
|
||||
assertEquals("sql.telemetry.mozilla",
|
||||
ActivityStream.extractLabel("https://sql.telemetry.mozilla.org/"));
|
||||
ActivityStream.extractLabel("https://sql.telemetry.mozilla.org/", true));
|
||||
|
||||
assertEquals("sso.mozilla",
|
||||
ActivityStream.extractLabel("http://sso.mozilla.com/"));
|
||||
ActivityStream.extractLabel("http://sso.mozilla.com/", true));
|
||||
|
||||
assertEquals("youtube",
|
||||
ActivityStream.extractLabel("http://youtube.com/"));
|
||||
ActivityStream.extractLabel("http://youtube.com/", true));
|
||||
|
||||
assertEquals("images.google",
|
||||
ActivityStream.extractLabel("http://images.google.com/"));
|
||||
ActivityStream.extractLabel("http://images.google.com/", true));
|
||||
|
||||
assertEquals("smile.amazon",
|
||||
ActivityStream.extractLabel("http://smile.amazon.com/"));
|
||||
ActivityStream.extractLabel("http://smile.amazon.com/", true));
|
||||
|
||||
assertEquals("localhost",
|
||||
ActivityStream.extractLabel("http://localhost:5000/"));
|
||||
ActivityStream.extractLabel("http://localhost:5000/", true));
|
||||
|
||||
assertEquals("independent",
|
||||
ActivityStream.extractLabel("http://www.independent.co.uk/"));
|
||||
ActivityStream.extractLabel("http://www.independent.co.uk/", true));
|
||||
|
||||
// With path
|
||||
|
||||
assertEquals("firefox",
|
||||
ActivityStream.extractLabel("https://addons.mozilla.org/en-US/firefox/"));
|
||||
ActivityStream.extractLabel("https://addons.mozilla.org/en-US/firefox/", true));
|
||||
|
||||
assertEquals("activity-stream",
|
||||
ActivityStream.extractLabel("https://trello.com/b/KX3hV8XS/activity-stream"));
|
||||
ActivityStream.extractLabel("https://trello.com/b/KX3hV8XS/activity-stream", true));
|
||||
|
||||
assertEquals("activity-stream",
|
||||
ActivityStream.extractLabel("https://github.com/mozilla/activity-stream"));
|
||||
ActivityStream.extractLabel("https://github.com/mozilla/activity-stream", true));
|
||||
|
||||
assertEquals("sidekiq",
|
||||
ActivityStream.extractLabel("https://dispatch-news.herokuapp.com/sidekiq"));
|
||||
ActivityStream.extractLabel("https://dispatch-news.herokuapp.com/sidekiq", true));
|
||||
|
||||
assertEquals("nchapman",
|
||||
ActivityStream.extractLabel("https://github.com/nchapman/"));
|
||||
ActivityStream.extractLabel("https://github.com/nchapman/", true));
|
||||
|
||||
// Unusable paths
|
||||
|
||||
assertEquals("phonebook.mozilla", // instead of "login"
|
||||
ActivityStream.extractLabel("https://phonebook.mozilla.org/mellon/login?ReturnTo=https%3A%2F%2Fphonebook.mozilla.org%2F&IdP=http%3A%2F%2Fwww.okta.com"));
|
||||
ActivityStream.extractLabel("https://phonebook.mozilla.org/mellon/login?ReturnTo=https%3A%2F%2Fphonebook.mozilla.org%2F&IdP=http%3A%2F%2Fwww.okta.com", true));
|
||||
|
||||
assertEquals("ipay.adp", // instead of "index.jsf"
|
||||
ActivityStream.extractLabel("https://ipay.adp.com/iPay/index.jsf"));
|
||||
ActivityStream.extractLabel("https://ipay.adp.com/iPay/index.jsf", true));
|
||||
|
||||
assertEquals("calendar.google", // instead of "render"
|
||||
ActivityStream.extractLabel("https://calendar.google.com/calendar/render?pli=1#main_7"));
|
||||
ActivityStream.extractLabel("https://calendar.google.com/calendar/render?pli=1#main_7", true));
|
||||
|
||||
assertEquals("myworkday", // instead of "home.htmld"
|
||||
ActivityStream.extractLabel("https://www.myworkday.com/vhr_mozilla/d/home.htmld"));
|
||||
ActivityStream.extractLabel("https://www.myworkday.com/vhr_mozilla/d/home.htmld", true));
|
||||
|
||||
assertEquals("mail.google", // instead of "1"
|
||||
ActivityStream.extractLabel("https://mail.google.com/mail/u/1/#inbox"));
|
||||
ActivityStream.extractLabel("https://mail.google.com/mail/u/1/#inbox", true));
|
||||
|
||||
assertEquals("docs.google", // instead of "edit"
|
||||
ActivityStream.extractLabel("https://docs.google.com/presentation/d/11cyrcwhKTmBdEBIZ3szLO0-_Imrx2CGV2B9_LZHDrds/edit#slide=id.g15d41bb0f3_0_82"));
|
||||
ActivityStream.extractLabel("https://docs.google.com/presentation/d/11cyrcwhKTmBdEBIZ3szLO0-_Imrx2CGV2B9_LZHDrds/edit#slide=id.g15d41bb0f3_0_82", true));
|
||||
|
||||
// Special cases
|
||||
|
||||
assertEquals("irccloud.mozilla",
|
||||
ActivityStream.extractLabel("https://irccloud.mozilla.com/#!/ircs://irc1.dmz.scl3.mozilla.com:6697/%23universal-search"));
|
||||
ActivityStream.extractLabel("https://irccloud.mozilla.com/#!/ircs://irc1.dmz.scl3.mozilla.com:6697/%23universal-search", true));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExtractLabelWithoutPath() {
|
||||
assertEquals("addons.mozilla",
|
||||
ActivityStream.extractLabel("https://addons.mozilla.org/en-US/firefox/", false));
|
||||
|
||||
assertEquals("trello",
|
||||
ActivityStream.extractLabel("https://trello.com/b/KX3hV8XS/activity-stream", false));
|
||||
|
||||
assertEquals("github",
|
||||
ActivityStream.extractLabel("https://github.com/mozilla/activity-stream", false));
|
||||
|
||||
assertEquals("dispatch-news",
|
||||
ActivityStream.extractLabel("https://dispatch-news.herokuapp.com/sidekiq", false));
|
||||
|
||||
assertEquals("github",
|
||||
ActivityStream.extractLabel("https://github.com/nchapman/", false));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1164,4 +1164,4 @@ static const TransportSecurityPreload kPublicKeyPinningPreloadList[] = {
|
|||
|
||||
static const int32_t kUnknownId = -1;
|
||||
|
||||
static const PRTime kPreloadPKPinsExpirationTime = INT64_C(1485090925836000);
|
||||
static const PRTime kPreloadPKPinsExpirationTime = INT64_C(1485177390292000);
|
||||
|
|
|
@ -4,13 +4,14 @@
|
|||
0x.sk: could not connect to host
|
||||
0x1337.eu: could not connect to host
|
||||
0x44.net: did not receive HSTS header
|
||||
0xAA55.me: could not connect to host
|
||||
0xaa55.me: could not connect to host
|
||||
0xb612.org: could not connect to host
|
||||
1018hosting.nl: did not receive HSTS header
|
||||
1022996493.rsc.cdn77.org: could not connect to host
|
||||
10seos.com: did not receive HSTS header
|
||||
123plons.nl: [Exception... "Component returned failure code: 0x80004005 (NS_ERROR_FAILURE) [nsISiteSecurityService.processHeader]" nsresult: "0x80004005 (NS_ERROR_FAILURE)" location: "JS frame :: /builds/slave/m-cen-l64-periodicupdate-00000/getHSTSPreloadList.js :: processStsHeader :: line 121" data: no]
|
||||
12vpnchina.com: could not connect to host
|
||||
18f.gov: did not receive HSTS header
|
||||
18f.gsa.gov: did not receive HSTS header
|
||||
1a-jva.de: did not receive HSTS header
|
||||
1p.ro: could not connect to host
|
||||
|
@ -94,7 +95,6 @@ aevpn.net: could not connect to host
|
|||
affinitysync.com: could not connect to host
|
||||
aficionados.com.br: did not receive HSTS header
|
||||
afp548.tk: could not connect to host
|
||||
agalaxyfarfaraway.co.uk: could not connect to host
|
||||
agbremen.de: did not receive HSTS header
|
||||
agevio.com: could not connect to host
|
||||
agilebits.net: could not connect to host
|
||||
|
@ -106,6 +106,7 @@ ahabingo.com: did not receive HSTS header
|
|||
ahri.ovh: could not connect to host
|
||||
airbnb.com: did not receive HSTS header
|
||||
aircomms.com: did not receive HSTS header
|
||||
airproto.com: could not connect to host
|
||||
aishnair.com: could not connect to host
|
||||
aiticon.de: did not receive HSTS header
|
||||
aiw-thkoeln.online: could not connect to host
|
||||
|
@ -126,6 +127,7 @@ alecvannoten.be: did not receive HSTS header
|
|||
alela.fr: could not connect to host
|
||||
alessandro.pw: did not receive HSTS header
|
||||
alethearose.com: did not receive HSTS header
|
||||
alexberts.ch: did not receive HSTS header
|
||||
alexisabarca.com: did not receive HSTS header
|
||||
alfredxing.com: did not receive HSTS header
|
||||
alkami.com: did not receive HSTS header
|
||||
|
@ -169,6 +171,8 @@ aniplus.cf: could not connect to host
|
|||
aniplus.gq: could not connect to host
|
||||
aniplus.ml: could not connect to host
|
||||
ankakaak.com: could not connect to host
|
||||
ankaraprofesyonelnakliyat.com: did not receive HSTS header
|
||||
ankaraprofesyonelnakliyat.com.tr: did not receive HSTS header
|
||||
annabellaw.com: max-age too low: 0
|
||||
anomaly.ws: did not receive HSTS header
|
||||
anonboards.com: did not receive HSTS header
|
||||
|
@ -254,6 +258,7 @@ avec-ou-sans-ordonnance.fr: could not connect to host
|
|||
avinet.com: max-age too low: 0
|
||||
avqueen.cn: could not connect to host
|
||||
awg-mode.de: did not receive HSTS header
|
||||
awxg.com: could not connect to host
|
||||
axado.com.br: did not receive HSTS header
|
||||
axeny.com: did not receive HSTS header
|
||||
az.search.yahoo.com: did not receive HSTS header
|
||||
|
@ -276,7 +281,8 @@ bandb.xyz: could not connect to host
|
|||
barely.sexy: did not receive HSTS header
|
||||
bashcode.ninja: could not connect to host
|
||||
basicsolutionsus.com: did not receive HSTS header
|
||||
baumstark.ca: could not connect to host
|
||||
bassh.net: did not receive HSTS header
|
||||
baumstark.ca: did not receive HSTS header
|
||||
bazarstupava.sk: did not receive HSTS header
|
||||
bcbsmagentprofile.com: could not connect to host
|
||||
bccx.com: could not connect to host
|
||||
|
@ -284,6 +290,7 @@ bckp.de: could not connect to host
|
|||
bcm.com.au: max-age too low: 0
|
||||
bcnx.de: did not receive HSTS header
|
||||
bcsytv.com: could not connect to host
|
||||
bdikaros-network.net: could not connect to host
|
||||
be.search.yahoo.com: did not receive HSTS header
|
||||
beach-inspector.com: did not receive HSTS header
|
||||
beachi.es: could not connect to host
|
||||
|
@ -313,6 +320,7 @@ betplanning.it: did not receive HSTS header
|
|||
bets.de: did not receive HSTS header
|
||||
bettween.com: did not receive HSTS header
|
||||
betz.ro: did not receive HSTS header
|
||||
beulahtabernacle.com: could not connect to host
|
||||
bevapehappy.com: did not receive HSTS header
|
||||
bezorg.ninja: could not connect to host
|
||||
bf.am: max-age too low: 0
|
||||
|
@ -325,6 +333,7 @@ bienenblog.cc: could not connect to host
|
|||
bigbrownpromotions.com.au: did not receive HSTS header
|
||||
bigdinosaur.org: did not receive HSTS header
|
||||
bigshinylock.minazo.net: could not connect to host
|
||||
bikiniseli.com: could not connect to host
|
||||
bildiri.ci: did not receive HSTS header
|
||||
bildschirmflackern.de: did not receive HSTS header
|
||||
billin.net: did not receive HSTS header
|
||||
|
@ -387,6 +396,7 @@ boomerang.com: could not connect to host
|
|||
bootjp.me: did not receive HSTS header
|
||||
boringsecurity.net: could not connect to host
|
||||
boris.one: did not receive HSTS header
|
||||
bosun.io: could not connect to host
|
||||
botox.bz: did not receive HSTS header
|
||||
bouwbedrijfpurmerend.nl: did not receive HSTS header
|
||||
bowlroll.net: max-age too low: 0
|
||||
|
@ -507,8 +517,10 @@ changelab.cc: max-age too low: 0
|
|||
chaos.fail: did not receive HSTS header
|
||||
chargejuice.com: [Exception... "Component returned failure code: 0x80004005 (NS_ERROR_FAILURE) [nsISiteSecurityService.processHeader]" nsresult: "0x80004005 (NS_ERROR_FAILURE)" location: "JS frame :: /builds/slave/m-cen-l64-periodicupdate-00000/getHSTSPreloadList.js :: processStsHeader :: line 121" data: no]
|
||||
charnleyhouse.co.uk: max-age too low: 604800
|
||||
chartpen.com: did not receive HSTS header
|
||||
chartstoffarm.de: max-age too low: 10
|
||||
chatbot.me: did not receive HSTS header
|
||||
chateau-belvoir.com: did not receive HSTS header
|
||||
chateauconstellation.ch: did not receive HSTS header
|
||||
chatup.cf: could not connect to host
|
||||
chaulootz.com: could not connect to host
|
||||
|
@ -524,7 +536,6 @@ cherysunzhang.com: max-age too low: 7776000
|
|||
chihiro.xyz: could not connect to host
|
||||
chijiokeindustries.co.uk: did not receive HSTS header
|
||||
childcaresolutionscny.org: did not receive HSTS header
|
||||
chiralsoftware.com: could not connect to host
|
||||
chirgui.eu: could not connect to host
|
||||
chiru.no: did not receive HSTS header
|
||||
chm.vn: did not receive HSTS header
|
||||
|
@ -549,6 +560,7 @@ cityoflaurel.org: did not receive HSTS header
|
|||
classicspublishing.com: could not connect to host
|
||||
clcleaningco.com: could not connect to host
|
||||
cleaningsquad.ca: max-age too low: 0
|
||||
clemovementlaw.com: could not connect to host
|
||||
clerkendweller.uk: could not connect to host
|
||||
cleververmarkten.com: could not connect to host
|
||||
cleververmarkten.de: could not connect to host
|
||||
|
@ -619,7 +631,6 @@ constructionjobs.com: did not receive HSTS header
|
|||
contactbig.com: did not receive HSTS header
|
||||
content-api-dev.azurewebsites.net: could not connect to host
|
||||
continuumgaming.com: could not connect to host
|
||||
converter.ml: could not connect to host
|
||||
coolchevy.org.ua: did not receive HSTS header
|
||||
coralproject.net: did not receive HSTS header
|
||||
coralrosado.com.br: did not receive HSTS header
|
||||
|
@ -686,6 +697,7 @@ cupidmentor.com: did not receive HSTS header
|
|||
curroapp.com: could not connect to host
|
||||
custe.rs: could not connect to host
|
||||
cyanogenmod.xxx: could not connect to host
|
||||
cyberlab.kiev.ua: could not connect to host
|
||||
cybershambles.com: could not connect to host
|
||||
cycleluxembourg.lu: did not receive HSTS header
|
||||
cydia-search.io: could not connect to host
|
||||
|
@ -703,6 +715,7 @@ danijobs.com: could not connect to host
|
|||
danpiel.net: could not connect to host
|
||||
danrl.de: did not receive HSTS header
|
||||
daolerp.xyz: could not connect to host
|
||||
dargasia.is: could not connect to host
|
||||
dario.im: could not connect to host
|
||||
dark-x.cf: could not connect to host
|
||||
darkengine.io: could not connect to host
|
||||
|
@ -838,12 +851,15 @@ dropcam.com: did not receive HSTS header
|
|||
drtroyhendrickson.com: could not connect to host
|
||||
drumbandesperanto.nl: could not connect to host
|
||||
dshiv.io: could not connect to host
|
||||
dubrovskiy.net: could not connect to host
|
||||
dubrovskiy.pro: could not connect to host
|
||||
duesee.org: could not connect to host
|
||||
duria.de: max-age too low: 3600
|
||||
dutch1.nl: did not receive HSTS header
|
||||
dwhd.org: [Exception... "Component returned failure code: 0x80004005 (NS_ERROR_FAILURE) [nsISiteSecurityService.processHeader]" nsresult: "0x80004005 (NS_ERROR_FAILURE)" location: "JS frame :: /builds/slave/m-cen-l64-periodicupdate-00000/getHSTSPreloadList.js :: processStsHeader :: line 121" data: no]
|
||||
dycontrol.de: could not connect to host
|
||||
dylanscott.com.au: did not receive HSTS header
|
||||
dynamize.solutions: could not connect to host
|
||||
dzimejl.sk: did not receive HSTS header
|
||||
dzlibs.io: could not connect to host
|
||||
e-aut.net: could not connect to host
|
||||
|
@ -853,6 +869,7 @@ earlybirdsnacks.com: did not receive HSTS header
|
|||
easychiller.org: could not connect to host
|
||||
easyhaul.com: did not receive HSTS header
|
||||
eatlowcarb.de: did not receive HSTS header
|
||||
eauclairecommerce.com: could not connect to host
|
||||
ebecs.com: did not receive HSTS header
|
||||
ebermannstadt.de: max-age too low: 0
|
||||
ebfe.pw: did not receive HSTS header
|
||||
|
@ -879,6 +896,7 @@ ehrenamt-skpfcw.de: could not connect to host
|
|||
eicfood.com: could not connect to host
|
||||
elaintehtaat.fi: did not receive HSTS header
|
||||
elanguest.pl: could not connect to host
|
||||
elaon.de: could not connect to host
|
||||
elblein.de: could not connect to host
|
||||
electricianforum.co.uk: could not connect to host
|
||||
electromc.com: could not connect to host
|
||||
|
@ -895,7 +913,7 @@ emeldi-commerce.com: max-age too low: 0
|
|||
emilyhorsman.com: could not connect to host
|
||||
emmable.com: could not connect to host
|
||||
emnitech.com: could not connect to host
|
||||
empleostampico.com: did not receive HSTS header
|
||||
empleostampico.com: could not connect to host
|
||||
enargia.jp: max-age too low: 0
|
||||
encode.space: did not receive HSTS header
|
||||
encoder.pw: could not connect to host
|
||||
|
@ -921,6 +939,7 @@ equate.net.au: could not connect to host
|
|||
equatetechnologies.com.au: could not connect to host
|
||||
equilibre-yoga-jennifer-will.com: could not connect to host
|
||||
eressea.xyz: could not connect to host
|
||||
ericyl.com: could not connect to host
|
||||
eriix.org: could not connect to host
|
||||
eromixx.com: did not receive HSTS header
|
||||
erotalia.es: could not connect to host
|
||||
|
@ -945,7 +964,7 @@ etula.ga: could not connect to host
|
|||
euanbaines.com: did not receive HSTS header
|
||||
eucl3d.com: did not receive HSTS header
|
||||
eulerpi.io: could not connect to host
|
||||
euph.eu: did not receive HSTS header
|
||||
euph.eu: could not connect to host
|
||||
euren.se: could not connect to host
|
||||
euroshop24.net: could not connect to host
|
||||
evantage.org: could not connect to host
|
||||
|
@ -954,7 +973,6 @@ evi.be: did not receive HSTS header
|
|||
evin.ml: could not connect to host
|
||||
evomon.com: could not connect to host
|
||||
evossd.tk: could not connect to host
|
||||
exceltobarcode.com: could not connect to host
|
||||
exfiles.cz: did not receive HSTS header
|
||||
exgravitus.com: could not connect to host
|
||||
exitus.jp: max-age too low: 0
|
||||
|
@ -1033,14 +1051,14 @@ fj.search.yahoo.com: did not receive HSTS header
|
|||
flags.ninja: could not connect to host
|
||||
flam.io: could not connect to host
|
||||
flamewall.net: could not connect to host
|
||||
flashback.org: could not connect to host
|
||||
fleximus.org: could not connect to host
|
||||
fleximus.org: did not receive HSTS header
|
||||
fliexer.com: did not receive HSTS header
|
||||
floless.co.uk: did not receive HSTS header
|
||||
florian-lillpopp.de: max-age too low: 10
|
||||
florianlillpopp.de: max-age too low: 10
|
||||
floridaescapes.co.uk: did not receive HSTS header
|
||||
flouartistique.ch: could not connect to host
|
||||
flow.su: could not connect to host
|
||||
flowersandclouds.com: could not connect to host
|
||||
flushstudios.com: did not receive HSTS header
|
||||
flyaces.com: did not receive HSTS header
|
||||
|
@ -1058,7 +1076,6 @@ foreveralone.io: could not connect to host
|
|||
forex-dan.com: did not receive HSTS header
|
||||
formini.dz: did not receive HSTS header
|
||||
formula.cf: could not connect to host
|
||||
fortworth.ch: could not connect to host
|
||||
fotiu.com: could not connect to host
|
||||
fotm.net: did not receive HSTS header
|
||||
fotografosexpertos.com: did not receive HSTS header
|
||||
|
@ -1073,6 +1090,7 @@ frangor.info: did not receive HSTS header
|
|||
frankl.in: did not receive HSTS header
|
||||
fransallen.com: did not receive HSTS header
|
||||
frasys.io: did not receive HSTS header
|
||||
free-your-pc.com: did not receive HSTS header
|
||||
freeflow.tv: could not connect to host
|
||||
freekdevries.nl: could not connect to host
|
||||
freematthale.net: did not receive HSTS header
|
||||
|
@ -1130,7 +1148,6 @@ geli-graphics.com: did not receive HSTS header
|
|||
gem-indonesia.net: could not connect to host
|
||||
genuu.com: could not connect to host
|
||||
genuxation.com: could not connect to host
|
||||
genuxtsg.com: could not connect to host
|
||||
genyaa.com: could not connect to host
|
||||
gerencianet.com.br: did not receive HSTS header
|
||||
get.zenpayroll.com: did not receive HSTS header
|
||||
|
@ -1144,7 +1161,7 @@ getlifti.com: did not receive HSTS header
|
|||
getlolaccount.com: could not connect to host
|
||||
getmassage.com.ng: did not receive HSTS header
|
||||
getsello.com: did not receive HSTS header
|
||||
getwashdaddy.com: did not receive HSTS header
|
||||
getwashdaddy.com: could not connect to host
|
||||
gfhgiro.nl: [Exception... "Component returned failure code: 0x80004005 (NS_ERROR_FAILURE) [nsISiteSecurityService.processHeader]" nsresult: "0x80004005 (NS_ERROR_FAILURE)" location: "JS frame :: /builds/slave/m-cen-l64-periodicupdate-00000/getHSTSPreloadList.js :: processStsHeader :: line 121" data: no]
|
||||
gfm.tech: could not connect to host
|
||||
gfournier.ca: could not connect to host
|
||||
|
@ -1152,6 +1169,7 @@ gfwsb.ml: could not connect to host
|
|||
gheorghesarcov.ga: could not connect to host
|
||||
gheorghesarcov.tk: could not connect to host
|
||||
gigacloud.org: could not connect to host
|
||||
gigacog.com: could not connect to host
|
||||
gilgaz.com: did not receive HSTS header
|
||||
gilly.berlin: did not receive HSTS header
|
||||
gingali.de: did not receive HSTS header
|
||||
|
@ -1175,6 +1193,7 @@ gmail.com: did not receive HSTS header (error ignored - included regardless)
|
|||
gmantra.org: could not connect to host
|
||||
gmoes.at: max-age too low: 600000
|
||||
go.ax: did not receive HSTS header
|
||||
goabonga.com: could not connect to host
|
||||
goaltree.ch: did not receive HSTS header
|
||||
goarmy.eu: [Exception... "Component returned failure code: 0x80004005 (NS_ERROR_FAILURE) [nsISiteSecurityService.processHeader]" nsresult: "0x80004005 (NS_ERROR_FAILURE)" location: "JS frame :: /builds/slave/m-cen-l64-periodicupdate-00000/getHSTSPreloadList.js :: processStsHeader :: line 121" data: no]
|
||||
goat.xyz: did not receive HSTS header
|
||||
|
@ -1195,6 +1214,7 @@ googlemail.com: did not receive HSTS header (error ignored - included regardless
|
|||
googleplex.com: could not connect to host (error ignored - included regardless)
|
||||
gorilla-gym.site: could not connect to host
|
||||
goto.google.com: did not receive HSTS header (error ignored - included regardless)
|
||||
gotowned.org: did not receive HSTS header
|
||||
gottcode.org: did not receive HSTS header
|
||||
govillemo.ca: did not receive HSTS header
|
||||
gowe.wang: could not connect to host
|
||||
|
@ -1213,7 +1233,6 @@ greenvines.com.tw: did not receive HSTS header
|
|||
gregorytlee.me: did not receive HSTS header
|
||||
greplin.com: could not connect to host
|
||||
grigalanzsoftware.com: could not connect to host
|
||||
grossell.ru: did not receive HSTS header
|
||||
groups.google.com: did not receive HSTS header (error ignored - included regardless)
|
||||
grozip.com: could not connect to host
|
||||
grunex.com: did not receive HSTS header
|
||||
|
@ -1227,7 +1246,6 @@ gtraxapp.com: could not connect to host
|
|||
guava.studio: did not receive HSTS header
|
||||
guilde-vindicta.fr: did not receive HSTS header
|
||||
gunnarhafdal.com: did not receive HSTS header
|
||||
guoqiang.info: did not receive HSTS header
|
||||
gurusupe.com: could not connect to host
|
||||
gvt2.com: could not connect to host (error ignored - included regardless)
|
||||
gvt3.com: could not connect to host (error ignored - included regardless)
|
||||
|
@ -1264,7 +1282,6 @@ harabuhouse.com: did not receive HSTS header
|
|||
harmonycosmetic.com: max-age too low: 300
|
||||
harristony.com: could not connect to host
|
||||
harvestapp.com: [Exception... "Component returned failure code: 0x80004005 (NS_ERROR_FAILURE) [nsISiteSecurityService.processHeader]" nsresult: "0x80004005 (NS_ERROR_FAILURE)" location: "JS frame :: /builds/slave/m-cen-l64-periodicupdate-00000/getHSTSPreloadList.js :: processStsHeader :: line 121" data: no]
|
||||
harvester.fr: could not connect to host
|
||||
harvestrenewal.org: did not receive HSTS header
|
||||
harz.cloud: could not connect to host
|
||||
has.vision: could not connect to host
|
||||
|
@ -1326,6 +1343,7 @@ hookandloom.com: did not receive HSTS header
|
|||
horosho.in: could not connect to host
|
||||
horseboners.xxx: did not receive HSTS header
|
||||
hortifarm.ro: could not connect to host
|
||||
hosiet.me: could not connect to host
|
||||
hosted-service.com: did not receive HSTS header
|
||||
hostedtalkgadget.google.com: did not receive HSTS header (error ignored - included regardless)
|
||||
hostgarou.com: did not receive HSTS header
|
||||
|
@ -1348,7 +1366,7 @@ hugosleep.com.au: did not receive HSTS header
|
|||
huiser.nl: could not connect to host
|
||||
humblefinances.com: could not connect to host
|
||||
humpteedumptee.in: did not receive HSTS header
|
||||
hurd.is: could not connect to host
|
||||
huntshomeinspections.com: could not connect to host
|
||||
hurricanelabs.com: did not receive HSTS header
|
||||
hydra.ws: could not connect to host
|
||||
i-jp.net: could not connect to host
|
||||
|
@ -1385,6 +1403,7 @@ ilikerainbows.co: could not connect to host
|
|||
ilikerainbows.co.uk: could not connect to host
|
||||
ilmconpm.de: did not receive HSTS header
|
||||
ilona.graphics: max-age too low: 3600
|
||||
imakepoems.net: could not connect to host
|
||||
ime.moe: could not connect to host
|
||||
imguoguo.com: did not receive HSTS header
|
||||
imim.pw: did not receive HSTS header
|
||||
|
@ -1502,7 +1521,6 @@ jannyrijneveld.nl: did not receive HSTS header
|
|||
janus-engineering.de: did not receive HSTS header
|
||||
japlex.com: could not connect to host
|
||||
jaqen.ch: could not connect to host
|
||||
jardins-utopie.net: did not receive HSTS header
|
||||
jaredeberle.org: did not receive HSTS header
|
||||
jaroslavtrsek.cz: did not receive HSTS header
|
||||
jartza.org: could not connect to host
|
||||
|
@ -1535,6 +1553,7 @@ jikken.de: could not connect to host
|
|||
jimas.eu: did not receive HSTS header
|
||||
jimmycai.org: max-age too low: 10368000
|
||||
jinbo123.com: did not receive HSTS header
|
||||
jiyuu-ni.net: could not connect to host
|
||||
jkb.pics: could not connect to host
|
||||
jkbuster.com: could not connect to host
|
||||
jmdekker.it: could not connect to host
|
||||
|
@ -1579,11 +1598,12 @@ jwilsson.me: could not connect to host
|
|||
jxm.in: could not connect to host
|
||||
k-dev.de: could not connect to host
|
||||
ka-clan.com: could not connect to host
|
||||
kabus.org: could not connect to host
|
||||
kadioglumakina.com.tr: did not receive HSTS header
|
||||
kahopoon.net: could not connect to host
|
||||
kaisers.de: did not receive HSTS header
|
||||
kalami.nl: could not connect to host
|
||||
kall.is: could not connect to host
|
||||
kalian.cz: could not connect to host
|
||||
kamikano.com: could not connect to host
|
||||
kaplatz.is: could not connect to host
|
||||
kapucini.si: max-age too low: 0
|
||||
|
@ -1603,12 +1623,10 @@ keeley.gq: could not connect to host
|
|||
keeley.ml: could not connect to host
|
||||
keeleysam.me: could not connect to host
|
||||
keepclean.me: could not connect to host
|
||||
keifel.de: could not connect to host
|
||||
kerangalam.com: did not receive HSTS header
|
||||
kerksanders.nl: did not receive HSTS header
|
||||
kermadec.net: could not connect to host
|
||||
kernl.us: did not receive HSTS header
|
||||
ketosecology.co.uk: could not connect to host
|
||||
kevinapease.com: max-age too low: 0
|
||||
keymaster.lookout.com: did not receive HSTS header
|
||||
kg-rating.com: did not receive HSTS header
|
||||
|
@ -1617,6 +1635,7 @@ kickass.al: could not connect to host
|
|||
kid-dachau.de: did not receive HSTS header
|
||||
kiel-media.de: did not receive HSTS header
|
||||
kimpost.org: could not connect to host
|
||||
kinderwagen-test24.de: did not receive HSTS header
|
||||
kingmanhall.org: could not connect to host
|
||||
kinnon.enterprises: could not connect to host
|
||||
kinogb.net: did not receive HSTS header
|
||||
|
@ -1624,6 +1643,7 @@ kionetworks.com: did not receive HSTS header
|
|||
kirkforcongress.com: could not connect to host
|
||||
kirkforsenate.com: did not receive HSTS header
|
||||
kirkpatrickdavis.com: could not connect to host
|
||||
kisa.io: could not connect to host
|
||||
kissart.net: did not receive HSTS header
|
||||
kitakemon.com: could not connect to host
|
||||
kitchenpunx.com: [Exception... "Component returned failure code: 0x80004005 (NS_ERROR_FAILURE) [nsISiteSecurityService.processHeader]" nsresult: "0x80004005 (NS_ERROR_FAILURE)" location: "JS frame :: /builds/slave/m-cen-l64-periodicupdate-00000/getHSTSPreloadList.js :: processStsHeader :: line 121" data: no]
|
||||
|
@ -1661,7 +1681,6 @@ krmela.com: could not connect to host
|
|||
kroetenfuchs.de: could not connect to host
|
||||
kropkait.pl: could not connect to host
|
||||
krouzkyliduska.cz: [Exception... "Component returned failure code: 0x80004005 (NS_ERROR_FAILURE) [nsISiteSecurityService.processHeader]" nsresult: "0x80004005 (NS_ERROR_FAILURE)" location: "JS frame :: /builds/slave/m-cen-l64-periodicupdate-00000/getHSTSPreloadList.js :: processStsHeader :: line 121" data: no]
|
||||
kruu.de: could not connect to host
|
||||
ksfh-mail.de: could not connect to host
|
||||
kstan.me: could not connect to host
|
||||
kueulangtahunanak.net: could not connect to host
|
||||
|
@ -1674,6 +1693,7 @@ kurehun.org: could not connect to host
|
|||
kurz.pw: did not receive HSTS header
|
||||
kusaka-abacus.jp: max-age too low: 0
|
||||
kweddingplanning.com: did not receive HSTS header
|
||||
kwidz.fr: did not receive HSTS header
|
||||
kwok.tv: could not connect to host
|
||||
kyanite.co: could not connect to host
|
||||
kylinj.com: could not connect to host
|
||||
|
@ -1687,7 +1707,6 @@ labs.moscow: did not receive HSTS header
|
|||
lachlankidson.net: did not receive HSTS header
|
||||
lacliniquefinanciere.com: did not receive HSTS header
|
||||
laf.in.net: did not receive HSTS header
|
||||
lafkor.de: could not connect to host
|
||||
lagalerievirtuelle.fr: did not receive HSTS header
|
||||
lagarderob.ru: max-age too low: 0
|
||||
lagoza.name: could not connect to host
|
||||
|
@ -1774,7 +1793,6 @@ livekaarten.be: did not receive HSTS header
|
|||
livekaarten.nl: did not receive HSTS header
|
||||
livekort.dk: did not receive HSTS header
|
||||
livekort.se: did not receive HSTS header
|
||||
lixingcong.com: could not connect to host
|
||||
loadso.me: could not connect to host
|
||||
loafbox.com: could not connect to host
|
||||
locktheirphone.com: could not connect to host
|
||||
|
@ -1826,13 +1844,13 @@ lv.search.yahoo.com: did not receive HSTS header
|
|||
lzkill.com: did not receive HSTS header
|
||||
m-ali.xyz: did not receive HSTS header
|
||||
m.gparent.org: could not connect to host
|
||||
m2tc.fr: could not connect to host
|
||||
m3-gmbh.de: did not receive HSTS header
|
||||
m82labs.com: did not receive HSTS header
|
||||
maarten.nyc: did not receive HSTS header
|
||||
maartenvandekamp.nl: did not receive HSTS header
|
||||
macchaberrycream.com: could not connect to host
|
||||
macchedil.com: did not receive HSTS header
|
||||
macgeneral.de: did not receive HSTS header
|
||||
madars.org: did not receive HSTS header
|
||||
maddin.ga: could not connect to host
|
||||
madebymagnitude.com: did not receive HSTS header
|
||||
|
@ -1876,6 +1894,7 @@ markusweimar.de: did not receive HSTS header
|
|||
marleyresort.com: did not receive HSTS header
|
||||
marsble.com: did not receive HSTS header
|
||||
marshut.net: could not connect to host
|
||||
martiert.com: could not connect to host
|
||||
martijnvhoof.nl: could not connect to host
|
||||
martinsfamilyappliance.com: [Exception... "Component returned failure code: 0x80004005 (NS_ERROR_FAILURE) [nsISiteSecurityService.processHeader]" nsresult: "0x80004005 (NS_ERROR_FAILURE)" location: "JS frame :: /builds/slave/m-cen-l64-periodicupdate-00000/getHSTSPreloadList.js :: processStsHeader :: line 121" data: no]
|
||||
masjidtawheed.net: did not receive HSTS header
|
||||
|
@ -1923,7 +1942,7 @@ melted.pw: could not connect to host
|
|||
members.mayfirst.org: did not receive HSTS header
|
||||
mensmaximus.de: did not receive HSTS header
|
||||
menthix.net: could not connect to host
|
||||
mereckas.com: did not receive HSTS header
|
||||
mereckas.com: could not connect to host
|
||||
meritz.rocks: could not connect to host
|
||||
merson.me: could not connect to host
|
||||
meshok.ru: did not receive HSTS header
|
||||
|
@ -1955,6 +1974,7 @@ mijcorijneveld.nl: did not receive HSTS header
|
|||
mijn-email.org: could not connect to host
|
||||
mikaelemilsson.net: did not receive HSTS header
|
||||
mikeburns.com: did not receive HSTS header
|
||||
mikeg.de: did not receive HSTS header
|
||||
mikepair.net: did not receive HSTS header
|
||||
mikonmaa.fi: could not connect to host
|
||||
miku.be: could not connect to host
|
||||
|
@ -1985,6 +2005,7 @@ mobilekey.co: could not connect to host
|
|||
mobilemedics.com: did not receive HSTS header
|
||||
mobilethreat.net: could not connect to host
|
||||
mobilethreatnetwork.net: could not connect to host
|
||||
mockmyapp.com: could not connect to host
|
||||
mocloud.eu: could not connect to host
|
||||
modemagazines.co.uk: could not connect to host
|
||||
moebel-nagel.de: did not receive HSTS header
|
||||
|
@ -2121,6 +2142,7 @@ nextproject.us: could not connect to host
|
|||
ng-security.com: could not connect to host
|
||||
ngine.ch: did not receive HSTS header
|
||||
nginxnudes.com: could not connect to host
|
||||
ngt-service.ru: could not connect to host
|
||||
ni.search.yahoo.com: did not receive HSTS header
|
||||
nicestresser.fr: could not connect to host
|
||||
nicky.io: did not receive HSTS header
|
||||
|
@ -2132,6 +2154,7 @@ nightx.uk: could not connect to host
|
|||
niho.jp: [Exception... "Component returned failure code: 0x80004005 (NS_ERROR_FAILURE) [nsISiteSecurityService.processHeader]" nsresult: "0x80004005 (NS_ERROR_FAILURE)" location: "JS frame :: /builds/slave/m-cen-l64-periodicupdate-00000/getHSTSPreloadList.js :: processStsHeader :: line 121" data: no]
|
||||
nikomo.fi: could not connect to host
|
||||
ninhs.org: could not connect to host
|
||||
nippler.org: did not receive HSTS header
|
||||
nippombashi.net: did not receive HSTS header
|
||||
nipponcareers.com: did not receive HSTS header
|
||||
nixien.fr: could not connect to host
|
||||
|
@ -2189,6 +2212,7 @@ nz.search.yahoo.com: max-age too low: 172800
|
|||
nzb.cat: max-age too low: 7776000
|
||||
o0o.one: did not receive HSTS header
|
||||
oasis.mobi: did not receive HSTS header
|
||||
oasisim.net: could not connect to host
|
||||
obsydian.org: could not connect to host
|
||||
occentus.net: did not receive HSTS header
|
||||
ochaken.cf: could not connect to host
|
||||
|
@ -2212,6 +2236,7 @@ oneminute.io: did not receive HSTS header
|
|||
onepluscamps.com: did not receive HSTS header
|
||||
onespiritinc.com: did not receive HSTS header
|
||||
onet.space: could not connect to host
|
||||
oneway.ga: did not receive HSTS header
|
||||
onewpst.com: did not receive HSTS header
|
||||
oniichan.us: did not receive HSTS header
|
||||
online-casino.eu: did not receive HSTS header
|
||||
|
@ -2263,7 +2288,7 @@ otherstuff.nl: [Exception... "Component returned failure code: 0x80004005 (NS_ER
|
|||
otichi.com: did not receive HSTS header
|
||||
ottospora.nl: could not connect to host
|
||||
ourbank.com: did not receive HSTS header
|
||||
outdoorproducts.com: could not connect to host
|
||||
outetc.com: could not connect to host
|
||||
outsider.im: could not connect to host
|
||||
ouvirmusica.com.br: did not receive HSTS header
|
||||
ovenapp.io: did not receive HSTS header
|
||||
|
@ -2272,7 +2297,6 @@ oversight.io: could not connect to host
|
|||
overthinkingit.com: max-age too low: 3600
|
||||
owncloud.help: could not connect to host
|
||||
ownmovies.fr: could not connect to host
|
||||
oxygaming.com: could not connect to host
|
||||
oxynux.fr: could not connect to host
|
||||
p.linode.com: could not connect to host
|
||||
p8r.de: did not receive HSTS header
|
||||
|
@ -2290,7 +2314,6 @@ papeda.net: did not receive HSTS header
|
|||
papercard.co.uk: did not receive HSTS header
|
||||
papierniak.net: could not connect to host
|
||||
parentmail.co.uk: did not receive HSTS header
|
||||
parpaing-paillette.net: did not receive HSTS header
|
||||
particonpsplus.it: could not connect to host
|
||||
partijtjevoordevrijheid.nl: [Exception... "Component returned failure code: 0x80004005 (NS_ERROR_FAILURE) [nsISiteSecurityService.processHeader]" nsresult: "0x80004005 (NS_ERROR_FAILURE)" location: "JS frame :: /builds/slave/m-cen-l64-periodicupdate-00000/getHSTSPreloadList.js :: processStsHeader :: line 121" data: no]
|
||||
partyvan.it: could not connect to host
|
||||
|
@ -2309,8 +2332,8 @@ paster.li: did not receive HSTS header
|
|||
patientinsight.net: could not connect to host
|
||||
patt.us: did not receive HSTS header
|
||||
patterson.mp: could not connect to host
|
||||
pauladamsmith.com: could not connect to host
|
||||
paulchen.at: did not receive HSTS header
|
||||
paulewen.ca: could not connect to host
|
||||
paulshir.com: could not connect to host
|
||||
paulyang.cn: did not receive HSTS header
|
||||
paxwinkel.nl: did not receive HSTS header
|
||||
|
@ -2320,8 +2343,6 @@ payroll.ch: did not receive HSTS header
|
|||
pbapp.net: did not receive HSTS header
|
||||
pbprint.ru: max-age too low: 0
|
||||
pc-nf.de: could not connect to host
|
||||
pcfun.net: did not receive HSTS header
|
||||
pchax.net: did not receive HSTS header
|
||||
peissen.com: [Exception... "Component returned failure code: 0x80004005 (NS_ERROR_FAILURE) [nsISiteSecurityService.processHeader]" nsresult: "0x80004005 (NS_ERROR_FAILURE)" location: "JS frame :: /builds/slave/m-cen-l64-periodicupdate-00000/getHSTSPreloadList.js :: processStsHeader :: line 121" data: no]
|
||||
pekkapikkarainen.fi: could not connect to host
|
||||
pekkarik.ru: could not connect to host
|
||||
|
@ -2345,7 +2366,6 @@ petrolplus.ru: did not receive HSTS header
|
|||
pettsy.com: could not connect to host
|
||||
pewboards.com: could not connect to host
|
||||
pgpm.io: could not connect to host
|
||||
philosopherswool.com: could not connect to host
|
||||
phoenix.dj: could not connect to host
|
||||
phongmay24h.com: could not connect to host
|
||||
phurl.de: could not connect to host
|
||||
|
@ -2355,7 +2375,6 @@ picotronic.biz: could not connect to host
|
|||
picscare.co.uk: did not receive HSTS header
|
||||
piligrimname.com: could not connect to host
|
||||
pinesandneedles.com: did not receive HSTS header
|
||||
pinoyonlinetv.com: did not receive HSTS header
|
||||
pippen.io: could not connect to host
|
||||
pir9.com: max-age too low: 2592000
|
||||
piratedb.com: could not connect to host
|
||||
|
@ -2395,10 +2414,9 @@ poolsandstuff.com: did not receive HSTS header
|
|||
poris.web.id: did not receive HSTS header
|
||||
portalplatform.net: did not receive HSTS header
|
||||
poshpak.com: did not receive HSTS header
|
||||
posterspy.com: did not receive HSTS header
|
||||
postscheduler.org: could not connect to host
|
||||
posylka.de: did not receive HSTS header
|
||||
potatoheads.net: did not receive HSTS header
|
||||
potatofrom.space: could not connect to host
|
||||
poussinooz.fr: could not connect to host
|
||||
povitria.net: could not connect to host
|
||||
power99press.com: could not connect to host
|
||||
|
@ -2455,7 +2473,7 @@ punchr-kamikazee.rhcloud.com: did not receive HSTS header
|
|||
purewebmasters.com: could not connect to host
|
||||
purplemoon.mobi: did not receive HSTS header
|
||||
purplestar.mobi: did not receive HSTS header
|
||||
pushapp.org: did not receive HSTS header
|
||||
pushapp.org: could not connect to host
|
||||
pwnies.dk: could not connect to host
|
||||
py.search.yahoo.com: did not receive HSTS header
|
||||
pypi-mirrors.org: could not connect to host
|
||||
|
@ -2517,7 +2535,6 @@ reggae-cdmx.com: did not receive HSTS header
|
|||
reic.me: could not connect to host
|
||||
reisyukaku.org: did not receive HSTS header
|
||||
rejo.in: could not connect to host
|
||||
relayawards.com: could not connect to host
|
||||
relisten.nl: did not receive HSTS header
|
||||
remodela.com.ve: could not connect to host
|
||||
renem.net: did not receive HSTS header
|
||||
|
@ -2568,6 +2585,7 @@ rodney.id.au: did not receive HSTS header
|
|||
rodosto.com: did not receive HSTS header
|
||||
roeper.party: could not connect to host
|
||||
romans-place.me.uk: could not connect to host
|
||||
rommelwood.de: could not connect to host
|
||||
ronvandordt.info: did not receive HSTS header
|
||||
ronwo.de: max-age too low: 1
|
||||
room-checkin24.de: [Exception... "Component returned failure code: 0x80004005 (NS_ERROR_FAILURE) [nsISiteSecurityService.processHeader]" nsresult: "0x80004005 (NS_ERROR_FAILURE)" location: "JS frame :: /builds/slave/m-cen-l64-periodicupdate-00000/getHSTSPreloadList.js :: processStsHeader :: line 121" data: no]
|
||||
|
@ -2610,6 +2628,7 @@ rxv.cc: could not connect to host
|
|||
ryankearney.com: could not connect to host
|
||||
ryanteck.uk: did not receive HSTS header
|
||||
s007.co: could not connect to host
|
||||
safematix.com: could not connect to host
|
||||
sageth.com: max-age too low: 0
|
||||
sah3.net: could not connect to host
|
||||
saikarra.com: could not connect to host
|
||||
|
@ -2625,7 +2644,6 @@ samraskauskas.com: could not connect to host
|
|||
samsen.club: did not receive HSTS header
|
||||
sandviks.com: did not receive HSTS header
|
||||
sansemea.com: could not connect to host
|
||||
sapk.fr: could not connect to host
|
||||
sarah-beckett-harpist.com: did not receive HSTS header
|
||||
sarahsweetlife.com: could not connect to host
|
||||
sarisonproductions.com: could not connect to host
|
||||
|
@ -2659,6 +2677,7 @@ scrambler.in: could not connect to host
|
|||
scrapings.net: could not connect to host
|
||||
screenresolution.space: could not connect to host
|
||||
scribe.systems: could not connect to host
|
||||
scrion.com: did not receive HSTS header
|
||||
script.google.com: did not receive HSTS header (error ignored - included regardless)
|
||||
sdsl-speedtest.de: could not connect to host
|
||||
search-one.de: did not receive HSTS header
|
||||
|
@ -2768,6 +2787,7 @@ skk.io: could not connect to host
|
|||
skoda-clever-lead.de: could not connect to host
|
||||
skoda-im-dialog.de: could not connect to host
|
||||
skullhouse.nyc: did not receive HSTS header
|
||||
skyasker.com: did not receive HSTS header
|
||||
skyoy.com: did not receive HSTS header
|
||||
slashdesign.it: did not receive HSTS header
|
||||
slashem.me: did not receive HSTS header
|
||||
|
@ -2834,7 +2854,6 @@ souyar.us: could not connect to host
|
|||
sovereignshare.com: could not connect to host
|
||||
sown.dyndns.org: could not connect to host
|
||||
sowncloud.de: [Exception... "Component returned failure code: 0x80004005 (NS_ERROR_FAILURE) [nsISiteSecurityService.processHeader]" nsresult: "0x80004005 (NS_ERROR_FAILURE)" location: "JS frame :: /builds/slave/m-cen-l64-periodicupdate-00000/getHSTSPreloadList.js :: processStsHeader :: line 121" data: no]
|
||||
spacehost.de: did not receive HSTS header
|
||||
spacehq.org: max-age too low: 0
|
||||
spark.team: could not connect to host
|
||||
sparklingsparklers.com: did not receive HSTS header
|
||||
|
@ -2861,7 +2880,7 @@ sprybear.com: did not receive HSTS header
|
|||
square.gs: could not connect to host
|
||||
squatldf.org: [Exception... "Component returned failure code: 0x80004005 (NS_ERROR_FAILURE) [nsISiteSecurityService.processHeader]" nsresult: "0x80004005 (NS_ERROR_FAILURE)" location: "JS frame :: /builds/slave/m-cen-l64-periodicupdate-00000/getHSTSPreloadList.js :: processStsHeader :: line 121" data: no]
|
||||
sqzryang.com: max-age too low: 604800
|
||||
srna.sk: max-age too low: 120
|
||||
srna.sk: could not connect to host
|
||||
ss.wtf: did not receive HSTS header
|
||||
ssersay.com: did not receive HSTS header
|
||||
ssl.panoramio.com: did not receive HSTS header
|
||||
|
@ -2871,6 +2890,7 @@ ssmato.me: could not connect to host
|
|||
ssnc.org: max-age too low: 300
|
||||
stabletoken.com: could not connect to host
|
||||
stadjerspasonline.nl: could not connect to host
|
||||
starfm.de: could not connect to host
|
||||
stateofexception.io: could not connect to host
|
||||
static.or.at: could not connect to host
|
||||
staticanime.net: could not connect to host
|
||||
|
@ -2885,7 +2905,7 @@ stewartremodelingadvantage.com: could not connect to host
|
|||
stick2bike.de: did not receive HSTS header
|
||||
stig.io: did not receive HSTS header
|
||||
stigroom.com: could not connect to host
|
||||
stkbn.com: could not connect to host
|
||||
stkbn.com: did not receive HSTS header
|
||||
stmbgr.com: could not connect to host
|
||||
stn.me.uk: did not receive HSTS header
|
||||
stocktrade.de: could not connect to host
|
||||
|
@ -2918,10 +2938,12 @@ subtitle.rip: could not connect to host
|
|||
sudo.im: could not connect to host
|
||||
sudo.li: did not receive HSTS header
|
||||
suite73.org: could not connect to host
|
||||
suksit.com: could not connect to host
|
||||
sumoatm.com: did not receive HSTS header
|
||||
sumoscout.de: did not receive HSTS header
|
||||
suncountrymarine.com: did not receive HSTS header
|
||||
sunshinepress.org: could not connect to host
|
||||
superbabysitting.ch: could not connect to host
|
||||
supereight.net: did not receive HSTS header
|
||||
superiorfloridavacation.com: did not receive HSTS header
|
||||
supersalescontest.nl: did not receive HSTS header
|
||||
|
@ -2943,8 +2965,6 @@ syncer.jp: did not receive HSTS header
|
|||
syncserve.net: did not receive HSTS header
|
||||
syneic.com: did not receive HSTS header
|
||||
syno.gq: could not connect to host
|
||||
syrocon.ch: could not connect to host
|
||||
sys.tf: could not connect to host
|
||||
sysadmin.xyz: could not connect to host
|
||||
syso.name: could not connect to host
|
||||
szaszm.tk: max-age too low: 0
|
||||
|
@ -2956,6 +2976,7 @@ tageau.com: could not connect to host
|
|||
taglondon.org: did not receive HSTS header
|
||||
tails.com.ar: could not connect to host
|
||||
talk.google.com: did not receive HSTS header (error ignored - included regardless)
|
||||
talktwincities.com: could not connect to host
|
||||
tallr.se: could not connect to host
|
||||
tallshoe.com: could not connect to host
|
||||
tandarts-haarlem.nl: did not receive HSTS header
|
||||
|
@ -2963,6 +2984,7 @@ tanzhijun.com: did not receive HSTS header
|
|||
tapfinder.ca: could not connect to host
|
||||
tapka.cz: did not receive HSTS header
|
||||
taranis.re: could not connect to host
|
||||
taravancil.com: did not receive HSTS header
|
||||
tarhauskielto.fi: did not receive HSTS header
|
||||
tartaros.fi: could not connect to host
|
||||
taskstats.com: could not connect to host
|
||||
|
@ -3000,7 +3022,6 @@ tepid.org: could not connect to host
|
|||
terrax.berlin: could not connect to host
|
||||
terrax.info: could not connect to host
|
||||
terrax.net: could not connect to host
|
||||
terry.pub: did not receive HSTS header
|
||||
testandroid.xyz: could not connect to host
|
||||
testbawks.com: did not receive HSTS header
|
||||
testnode.xyz: could not connect to host
|
||||
|
@ -3049,6 +3070,7 @@ thinkcoding.org: could not connect to host
|
|||
thinlyveiledcontempt.com: could not connect to host
|
||||
thirdpartytrade.com: did not receive HSTS header
|
||||
thirty5.net: did not receive HSTS header
|
||||
thomasschweizer.net: could not connect to host
|
||||
thorncreek.net: did not receive HSTS header
|
||||
thumbtack.com: did not receive HSTS header
|
||||
tickopa.co.uk: could not connect to host
|
||||
|
@ -3067,12 +3089,12 @@ tipsyk.ru: could not connect to host
|
|||
tirex.media: did not receive HSTS header
|
||||
tittelbach.at: could not connect to host
|
||||
titties.ml: could not connect to host
|
||||
tjs.me: could not connect to host
|
||||
tkarstens.de: did not receive HSTS header
|
||||
tlo.hosting: could not connect to host
|
||||
tlo.network: could not connect to host
|
||||
tls.li: could not connect to host
|
||||
tm-solutions.eu: [Exception... "Component returned failure code: 0x80004005 (NS_ERROR_FAILURE) [nsISiteSecurityService.processHeader]" nsresult: "0x80004005 (NS_ERROR_FAILURE)" location: "JS frame :: /builds/slave/m-cen-l64-periodicupdate-00000/getHSTSPreloadList.js :: processStsHeader :: line 121" data: no]
|
||||
tmaward.net: could not connect to host
|
||||
tmprod.com: did not receive HSTS header
|
||||
tncnanet.com.br: could not connect to host
|
||||
tnrsca.jp: did not receive HSTS header
|
||||
|
@ -3083,6 +3105,7 @@ todo.is: did not receive HSTS header
|
|||
todobazar.es: could not connect to host
|
||||
tokyopopline.com: did not receive HSTS header
|
||||
tollmanz.com: did not receive HSTS header
|
||||
tombrossman.com: could not connect to host
|
||||
tomharling.co.uk: max-age too low: 86400
|
||||
tomharling.uk: max-age too low: 86400
|
||||
tommsy.com: did not receive HSTS header
|
||||
|
@ -3162,7 +3185,7 @@ ufotable.uk: max-age too low: 0
|
|||
ui8.net: did not receive HSTS header
|
||||
ukas.com: did not receive HSTS header
|
||||
ukrgadget.com: could not connect to host
|
||||
ulmo.dk: did not receive HSTS header
|
||||
ulmo.dk: could not connect to host
|
||||
ulrik.moe: could not connect to host
|
||||
ultros.io: did not receive HSTS header
|
||||
umidev.com: could not connect to host
|
||||
|
@ -3225,6 +3248,7 @@ vdcomp.cz: could not connect to host
|
|||
vechkasov.ru: did not receive HSTS header
|
||||
vemokin.net: did not receive HSTS header
|
||||
verifikatorindonesia.com: could not connect to host
|
||||
veriny.tf: did not receive HSTS header
|
||||
vermontcareergateway.org: could not connect to host
|
||||
versia.ru: did not receive HSTS header
|
||||
veryhax.de: could not connect to host
|
||||
|
@ -3289,6 +3313,7 @@ watchium.com: did not receive HSTS header
|
|||
watchweasel.com: did not receive HSTS header
|
||||
watsonhall.uk: could not connect to host
|
||||
wave.is: could not connect to host
|
||||
wdbgroup.co.uk: could not connect to host
|
||||
wealthfactory.com: [Exception... "Component returned failure code: 0x80004005 (NS_ERROR_FAILURE) [nsISiteSecurityService.processHeader]" nsresult: "0x80004005 (NS_ERROR_FAILURE)" location: "JS frame :: /builds/slave/m-cen-l64-periodicupdate-00000/getHSTSPreloadList.js :: processStsHeader :: line 121" data: no]
|
||||
wear2work.nl: did not receive HSTS header
|
||||
weaverhairextensions.nl: did not receive HSTS header
|
||||
|
@ -3309,6 +3334,7 @@ webtiles.co.uk: could not connect to host
|
|||
webtobesocial.de: could not connect to host
|
||||
webwork.pw: could not connect to host
|
||||
weddingenvelopes.co.uk: did not receive HSTS header
|
||||
wellsolveit.com: could not connect to host
|
||||
welpy.com: did not receive HSTS header
|
||||
weltmeisterschaft.net: could not connect to host
|
||||
weme.eu: could not connect to host
|
||||
|
@ -3362,7 +3388,6 @@ witzemaschine.com: max-age too low: 0
|
|||
wiz.biz: could not connect to host
|
||||
wlzhiyin.cn: could not connect to host
|
||||
wm-talk.net: did not receive HSTS header
|
||||
wod-stavby.cz: could not connect to host
|
||||
wohnungsbau-ludwigsburg.de: did not receive HSTS header
|
||||
woima.fi: max-age too low: 604800
|
||||
wolfesden.com: could not connect to host
|
||||
|
@ -3416,7 +3441,7 @@ xellos.ml: could not connect to host
|
|||
xenesisziarovky.sk: could not connect to host
|
||||
xett.com: could not connect to host
|
||||
xfive.de: did not receive HSTS header
|
||||
xfrag-networks.com: max-age too low: 2592000
|
||||
xfrag-networks.com: max-age too low: 86400
|
||||
xiaody.me: could not connect to host
|
||||
xiaolvmu.me: could not connect to host
|
||||
xiaoxiao.im: did not receive HSTS header
|
||||
|
@ -3471,6 +3496,7 @@ youcontrol.ru: could not connect to host
|
|||
yourstrongbox.com: could not connect to host
|
||||
yout.com: max-age too low: 60000
|
||||
yu.gg: did not receive HSTS header
|
||||
yuan.ga: did not receive HSTS header
|
||||
yuhen.ru: could not connect to host
|
||||
yunity.org: did not receive HSTS header
|
||||
yunzhu.li: did not receive HSTS header
|
||||
|
@ -3500,7 +3526,6 @@ zhaochen.xyz: could not connect to host
|
|||
zhaojin97.cn: max-age too low: 604800
|
||||
zhendingresources.com: max-age too low: 0
|
||||
zigcore.com.br: could not connect to host
|
||||
zinc-x.com: could not connect to host
|
||||
zirtue.io: could not connect to host
|
||||
ziyuanabc.xyz: could not connect to host
|
||||
zking.ga: could not connect to host
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -13,49 +13,45 @@ this.EXPORTED_SYMBOLS = [ "AutoCompletePopup" ];
|
|||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
Cu.import("resource://gre/modules/Services.jsm");
|
||||
|
||||
// nsITreeView implementation that feeds the autocomplete popup
|
||||
// with the search data.
|
||||
var AutoCompleteTreeView = {
|
||||
// AutoCompleteResultView is an abstraction around a list of results
|
||||
// we got back up from browser-content.js. It implements enough of
|
||||
// nsIAutoCompleteController and nsIAutoCompleteInput to make the
|
||||
// richlistbox popup work.
|
||||
var AutoCompleteResultView = {
|
||||
// nsISupports
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsITreeView,
|
||||
Ci.nsIAutoCompleteController]),
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsIAutoCompleteController,
|
||||
Ci.nsIAutoCompleteInput]),
|
||||
|
||||
// Private variables
|
||||
treeBox: null,
|
||||
results: [],
|
||||
|
||||
// nsITreeView
|
||||
selection: null,
|
||||
|
||||
get rowCount() { return this.results.length; },
|
||||
setTree: function(treeBox) { this.treeBox = treeBox; },
|
||||
getCellText: function(idx, column) { return this.results[idx].value },
|
||||
isContainer: function(idx) { return false; },
|
||||
getCellValue: function(idx, column) { return false },
|
||||
isContainerOpen: function(idx) { return false; },
|
||||
isContainerEmpty: function(idx) { return false; },
|
||||
isSeparator: function(idx) { return false; },
|
||||
isSorted: function() { return false; },
|
||||
isEditable: function(idx, column) { return false; },
|
||||
canDrop: function(idx, orientation, dt) { return false; },
|
||||
getLevel: function(idx) { return 0; },
|
||||
getParentIndex: function(idx) { return -1; },
|
||||
hasNextSibling: function(idx, after) { return idx < this.results.length - 1 },
|
||||
toggleOpenState: function(idx) { },
|
||||
getCellProperties: function(idx, column) { return this.results[idx].style || ""; },
|
||||
getRowProperties: function(idx) { return ""; },
|
||||
getImageSrc: function(idx, column) { return null; },
|
||||
getProgressMode : function(idx, column) { },
|
||||
cycleHeader: function(column) { },
|
||||
cycleCell: function(idx, column) { },
|
||||
selectionChanged: function() { },
|
||||
performAction: function(action) { },
|
||||
performActionOnCell: function(action, index, column) { },
|
||||
getColumnProperties: function(column) { return ""; },
|
||||
|
||||
// nsIAutoCompleteController
|
||||
get matchCount() {
|
||||
return this.rowCount;
|
||||
return this.results.length;
|
||||
},
|
||||
|
||||
getValueAt(index) {
|
||||
return this.results[index].value;
|
||||
},
|
||||
|
||||
getLabelAt(index) {
|
||||
// Unused by richlist autocomplete - see getCommentAt.
|
||||
return "";
|
||||
},
|
||||
|
||||
getCommentAt(index) {
|
||||
// The richlist autocomplete popup uses comment for its main
|
||||
// display of an item, which is why we're returning the label
|
||||
// here instead.
|
||||
return this.results[index].label;
|
||||
},
|
||||
|
||||
getStyleAt(index) {
|
||||
return this.results[index].style;
|
||||
},
|
||||
|
||||
getImageAt(index) {
|
||||
return this.results[index].image;
|
||||
},
|
||||
|
||||
handleEnter: function(aIsPopupSelection) {
|
||||
|
@ -64,6 +60,21 @@ var AutoCompleteTreeView = {
|
|||
|
||||
stopSearch: function() {},
|
||||
|
||||
searchString: "",
|
||||
|
||||
// nsIAutoCompleteInput
|
||||
get controller() {
|
||||
return this;
|
||||
},
|
||||
|
||||
get popup() {
|
||||
return null;
|
||||
},
|
||||
|
||||
_focus() {
|
||||
AutoCompletePopup.requestFocus();
|
||||
},
|
||||
|
||||
// Internal JS-only API
|
||||
clearResults: function() {
|
||||
this.results = [];
|
||||
|
@ -99,10 +110,25 @@ this.AutoCompletePopup = {
|
|||
},
|
||||
|
||||
handleEvent: function(evt) {
|
||||
if (evt.type === "popuphidden") {
|
||||
this.openedPopup = null;
|
||||
this.weakBrowser = null;
|
||||
evt.target.removeEventListener("popuphidden", this);
|
||||
switch (evt.type) {
|
||||
case "popupshowing": {
|
||||
this.sendMessageToBrowser("FormAutoComplete:PopupOpened");
|
||||
break;
|
||||
}
|
||||
|
||||
case "popuphidden": {
|
||||
AutoCompleteResultView.clearResults();
|
||||
this.sendMessageToBrowser("FormAutoComplete:PopupClosed");
|
||||
// adjustHeight clears the height from the popup so that
|
||||
// we don't have a big shrink effect if we closed with a
|
||||
// large list, and then open on a small one.
|
||||
this.openedPopup.adjustHeight();
|
||||
this.openedPopup = null;
|
||||
this.weakBrowser = null;
|
||||
evt.target.removeEventListener("popuphidden", this);
|
||||
evt.target.removeEventListener("popupshowing", this);
|
||||
break;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -134,20 +160,21 @@ this.AutoCompletePopup = {
|
|||
this.openedPopup.setAttribute("width", Math.max(100, rect.width));
|
||||
this.openedPopup.style.direction = dir;
|
||||
|
||||
AutoCompleteTreeView.setResults(results);
|
||||
this.openedPopup.view = AutoCompleteTreeView;
|
||||
AutoCompleteResultView.setResults(results);
|
||||
this.openedPopup.view = AutoCompleteResultView;
|
||||
this.openedPopup.selectedIndex = -1;
|
||||
this.openedPopup.invalidate();
|
||||
|
||||
if (results.length) {
|
||||
// Reset fields that were set from the last time the search popup was open
|
||||
this.openedPopup.mInput = null;
|
||||
this.openedPopup.mInput = AutoCompleteResultView;
|
||||
this.openedPopup.showCommentColumn = false;
|
||||
this.openedPopup.showImageColumn = false;
|
||||
this.openedPopup.addEventListener("popuphidden", this);
|
||||
this.openedPopup.addEventListener("popupshowing", this);
|
||||
this.openedPopup.openPopupAtScreenRect("after_start", rect.left, rect.top,
|
||||
rect.width, rect.height, false,
|
||||
false);
|
||||
this.openedPopup.addEventListener("popuphidden", this);
|
||||
this.openedPopup.invalidate();
|
||||
} else {
|
||||
this.closePopup();
|
||||
}
|
||||
|
@ -161,19 +188,18 @@ this.AutoCompletePopup = {
|
|||
if (!results.length) {
|
||||
this.closePopup();
|
||||
} else {
|
||||
AutoCompleteTreeView.setResults(results);
|
||||
// We need to re-set the view in order for the
|
||||
// tree to know the view has changed.
|
||||
this.openedPopup.view = AutoCompleteTreeView;
|
||||
AutoCompleteResultView.setResults(results);
|
||||
this.openedPopup.invalidate();
|
||||
}
|
||||
},
|
||||
|
||||
closePopup() {
|
||||
if (this.openedPopup) {
|
||||
this.openedPopup.closePopup();
|
||||
// Note that hidePopup() closes the popup immediately,
|
||||
// so popuphiding or popuphidden events will be fired
|
||||
// and handled during this call.
|
||||
this.openedPopup.hidePopup();
|
||||
}
|
||||
AutoCompleteTreeView.clearResults();
|
||||
},
|
||||
|
||||
removeLogin(login) {
|
||||
|
@ -189,7 +215,9 @@ this.AutoCompletePopup = {
|
|||
|
||||
switch (message.name) {
|
||||
case "FormAutoComplete:SelectBy": {
|
||||
this.openedPopup.selectBy(message.data.reverse, message.data.page);
|
||||
if (this.openedPopup) {
|
||||
this.openedPopup.selectBy(message.data.reverse, message.data.page);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -233,7 +261,7 @@ this.AutoCompletePopup = {
|
|||
// any cached data. This is necessary cause otherwise we'd clear data
|
||||
// only when starting a new search, but the next input could not support
|
||||
// autocomplete and it would end up inheriting the existing data.
|
||||
AutoCompleteTreeView.clearResults();
|
||||
AutoCompleteResultView.clearResults();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -246,17 +274,41 @@ this.AutoCompletePopup = {
|
|||
* Despite its name, handleEnter is what is called when the
|
||||
* user clicks on one of the items in the popup.
|
||||
*/
|
||||
handleEnter: function(aIsPopupSelection) {
|
||||
let browser = this.weakBrowser ? this.weakBrowser.get()
|
||||
: null;
|
||||
if (browser && this.openedPopup) {
|
||||
browser.messageManager.sendAsyncMessage(
|
||||
"FormAutoComplete:HandleEnter",
|
||||
{ selectedIndex: this.openedPopup.selectedIndex,
|
||||
isPopupSelection: aIsPopupSelection }
|
||||
);
|
||||
handleEnter(aIsPopupSelection) {
|
||||
if (this.openedPopup) {
|
||||
this.sendMessageToBrowser("FormAutoComplete:HandleEnter", {
|
||||
selectedIndex: this.openedPopup.selectedIndex,
|
||||
isPopupSelection: aIsPopupSelection,
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
stopSearch: function() {}
|
||||
/**
|
||||
* If a browser exists that AutoCompletePopup knows about,
|
||||
* sends it a message. Otherwise, this is a no-op.
|
||||
*
|
||||
* @param {string} msgName
|
||||
* The name of the message to send.
|
||||
* @param {object} data
|
||||
* The optional data to send with the message.
|
||||
*/
|
||||
sendMessageToBrowser(msgName, data) {
|
||||
let browser = this.weakBrowser ? this.weakBrowser.get()
|
||||
: null;
|
||||
if (browser) {
|
||||
browser.messageManager.sendAsyncMessage(msgName, data);
|
||||
}
|
||||
},
|
||||
|
||||
stopSearch: function() {},
|
||||
|
||||
/**
|
||||
* Sends a message to the browser requesting that the input
|
||||
* that the AutoCompletePopup is open for be focused.
|
||||
*/
|
||||
requestFocus: function() {
|
||||
if (this.openedPopup) {
|
||||
this.sendMessageToBrowser("FormAutoComplete:Focus");
|
||||
}
|
||||
},
|
||||
}
|
||||
|
|
|
@ -12,10 +12,9 @@ assert.ok(gAutocompletePopup, "Got autocomplete popup");
|
|||
var ParentUtils = {
|
||||
getMenuEntries() {
|
||||
let entries = [];
|
||||
let column = gAutocompletePopup.tree.columns[0];
|
||||
let numRows = gAutocompletePopup.tree.view.rowCount;
|
||||
let numRows = gAutocompletePopup.view.matchCount;
|
||||
for (let i = 0; i < numRows; i++) {
|
||||
entries.push(gAutocompletePopup.tree.view.getCellText(i, column));
|
||||
entries.push(gAutocompletePopup.view.getValueAt(i));
|
||||
}
|
||||
return entries;
|
||||
},
|
||||
|
@ -69,11 +68,10 @@ var ParentUtils = {
|
|||
|
||||
checkRowCount(expectedCount, expectedFirstValue = null) {
|
||||
ContentTaskUtils.waitForCondition(() => {
|
||||
return gAutocompletePopup.tree.view.rowCount === expectedCount &&
|
||||
return gAutocompletePopup.view.matchCount === expectedCount &&
|
||||
(!expectedFirstValue ||
|
||||
expectedCount <= 1 ||
|
||||
gAutocompletePopup.tree.view.getCellText(0, gAutocompletePopup.tree.columns[0]) ===
|
||||
expectedFirstValue);
|
||||
gAutocompletePopup.view.getValueAt(0) === expectedFirstValue);
|
||||
}, "Waiting for row count change: " + expectedCount + " First value: " + expectedFirstValue).then(() => {
|
||||
let results = this.getMenuEntries();
|
||||
sendAsyncMessage("gotMenuChange", { results });
|
||||
|
|
|
@ -1398,46 +1398,96 @@ let AutoCompletePopup = {
|
|||
QueryInterface: XPCOMUtils.generateQI([Ci.nsIAutoCompletePopup]),
|
||||
|
||||
_connected: false,
|
||||
|
||||
MESSAGES: [
|
||||
"FormAutoComplete:HandleEnter",
|
||||
"FormAutoComplete:PopupClosed",
|
||||
"FormAutoComplete:PopupOpened",
|
||||
"FormAutoComplete:RequestFocus",
|
||||
],
|
||||
|
||||
init: function() {
|
||||
// We need to wait for a content viewer to be available
|
||||
// before we can attach our AutoCompletePopup handler,
|
||||
// since nsFormFillController assumes one will exist
|
||||
// when we call attachToBrowser.
|
||||
let onDCL = () => {
|
||||
removeEventListener("DOMContentLoaded", onDCL);
|
||||
// Hook up the form fill autocomplete controller.
|
||||
let controller = Cc["@mozilla.org/satchel/form-fill-controller;1"]
|
||||
.getService(Ci.nsIFormFillController);
|
||||
controller.attachToBrowser(docShell,
|
||||
this.QueryInterface(Ci.nsIAutoCompletePopup));
|
||||
this._connected = true;
|
||||
};
|
||||
addEventListener("DOMContentLoaded", onDCL);
|
||||
addEventListener("unload", this);
|
||||
addEventListener("DOMContentLoaded", this);
|
||||
|
||||
for (let messageName of this.MESSAGES) {
|
||||
addMessageListener(messageName, this);
|
||||
}
|
||||
|
||||
this._input = null;
|
||||
this._popupOpen = false;
|
||||
|
||||
addMessageListener("FormAutoComplete:HandleEnter", message => {
|
||||
this.selectedIndex = message.data.selectedIndex;
|
||||
|
||||
let controller = Components.classes["@mozilla.org/autocomplete/controller;1"].
|
||||
getService(Components.interfaces.nsIAutoCompleteController);
|
||||
controller.handleEnter(message.data.isPopupSelection);
|
||||
});
|
||||
|
||||
addEventListener("unload", function() {
|
||||
AutoCompletePopup.destroy();
|
||||
});
|
||||
},
|
||||
|
||||
destroy: function() {
|
||||
if (this._connected) {
|
||||
let controller = Cc["@mozilla.org/satchel/form-fill-controller;1"]
|
||||
.getService(Ci.nsIFormFillController);
|
||||
|
||||
controller.detachFromBrowser(docShell);
|
||||
this._connected = false;
|
||||
}
|
||||
|
||||
removeEventListener("unload", this);
|
||||
removeEventListener("DOMContentLoaded", this);
|
||||
|
||||
for (let messageName of this.MESSAGES) {
|
||||
removeMessageListener(messageName, this);
|
||||
}
|
||||
},
|
||||
|
||||
handleEvent(event) {
|
||||
switch (event.type) {
|
||||
case "DOMContentLoaded": {
|
||||
removeEventListener("DOMContentLoaded", this);
|
||||
|
||||
// We need to wait for a content viewer to be available
|
||||
// before we can attach our AutoCompletePopup handler,
|
||||
// since nsFormFillController assumes one will exist
|
||||
// when we call attachToBrowser.
|
||||
|
||||
// Hook up the form fill autocomplete controller.
|
||||
let controller = Cc["@mozilla.org/satchel/form-fill-controller;1"]
|
||||
.getService(Ci.nsIFormFillController);
|
||||
controller.attachToBrowser(docShell,
|
||||
this.QueryInterface(Ci.nsIAutoCompletePopup));
|
||||
this._connected = true;
|
||||
break;
|
||||
}
|
||||
|
||||
case "unload": {
|
||||
this.destroy();
|
||||
break;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
receiveMessage(message) {
|
||||
switch (message.name) {
|
||||
case "FormAutoComplete:HandleEnter": {
|
||||
this.selectedIndex = message.data.selectedIndex;
|
||||
|
||||
let controller = Cc["@mozilla.org/autocomplete/controller;1"]
|
||||
.getService(Ci.nsIAutoCompleteController);
|
||||
controller.handleEnter(message.data.isPopupSelection);
|
||||
break;
|
||||
}
|
||||
|
||||
case "FormAutoComplete:PopupClosed": {
|
||||
this._popupOpen = false;
|
||||
break;
|
||||
}
|
||||
|
||||
case "FormAutoComplete:PopupOpened": {
|
||||
this._popupOpen = true;
|
||||
break;
|
||||
}
|
||||
|
||||
case "FormAutoComplete:RequestFocus": {
|
||||
if (this._input) {
|
||||
this._input.focus();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
get input () { return this._input; },
|
||||
|
@ -1471,10 +1521,13 @@ let AutoCompletePopup = {
|
|||
sendAsyncMessage("FormAutoComplete:MaybeOpenPopup",
|
||||
{ results, rect, dir });
|
||||
this._input = input;
|
||||
this._popupOpen = true;
|
||||
},
|
||||
|
||||
closePopup: function () {
|
||||
// We set this here instead of just waiting for the
|
||||
// PopupClosed message to do it so that we don't end
|
||||
// up in a state where the content thinks that a popup
|
||||
// is open when it isn't (or soon won't be).
|
||||
this._popupOpen = false;
|
||||
sendAsyncMessage("FormAutoComplete:ClosePopup", {});
|
||||
},
|
||||
|
@ -1516,7 +1569,7 @@ let AutoCompletePopup = {
|
|||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
AutoCompletePopup.init();
|
||||
|
|
|
@ -1124,6 +1124,10 @@ extends="chrome://global/content/bindings/popup.xml#popup">
|
|||
<body>
|
||||
<![CDATA[
|
||||
if (!this.mPopupOpen) {
|
||||
// It's possible that the panel is hidden initially
|
||||
// to avoid impacting startup / new window performance
|
||||
aInput.popup.hidden = false;
|
||||
|
||||
this.mInput = aInput;
|
||||
// clear any previous selection, see bugs 400671 and 488357
|
||||
this.selectedIndex = -1;
|
||||
|
|
Загрузка…
Ссылка в новой задаче