Merge inbound to mozilla-central r=merge a=merge

This commit is contained in:
Gurzau Raul 2017-12-09 00:36:15 +02:00
commit 91d3bc0100
119 changed files with 1448 additions and 1330 deletions

View File

@ -646,19 +646,21 @@ NotificationController::WillRefresh(mozilla::TimeStamp aTime)
nsIContent* textNode = entry->GetKey();
Accessible* textAcc = mDocument->GetAccessible(textNode);
// If the text node is not in tree or doesn't have frame then this case should
// have been handled already by content removal notifications.
// If the text node is not in tree or doesn't have a frame, or placed in
// another document, then this case should have been handled already by
// content removal notifications.
nsINode* containerNode = textNode->GetParentNode();
if (!containerNode) {
NS_ASSERTION(!textAcc,
"Text node was removed but accessible is kept alive!");
if (!containerNode ||
textNode->GetOwnerDocument() != mDocument->DocumentNode()) {
MOZ_ASSERT(!textAcc,
"Text node was removed but accessible is kept alive!");
continue;
}
nsIFrame* textFrame = textNode->GetPrimaryFrame();
if (!textFrame) {
NS_ASSERTION(!textAcc,
"Text node isn't rendered but accessible is kept alive!");
MOZ_ASSERT(!textAcc,
"Text node isn't rendered but accessible is kept alive!");
continue;
}

View File

@ -7,8 +7,13 @@ support-files =
moz.png
rich_moz_1.png
rich_moz_2.png
file_favicon.html
file_favicon.png
file_favicon.png^headers^
file_favicon_thirdParty.html
[browser_multiple_icons_in_short_timeframe.js]
[browser_rich_icons.js]
[browser_icon_discovery.js]
[browser_preferred_icons.js]
[browser_favicon_load.js]

View File

@ -9,17 +9,19 @@ const { classes: Cc, Constructor: CC, interfaces: Ci, utils: Cu } = Components;
const TEST_SITE = "http://example.net";
const TEST_THIRD_PARTY_SITE = "http://mochi.test:8888";
const TEST_PAGE = TEST_SITE + "/browser/browser/components/originattributes/" +
"test/browser/file_favicon.html";
const FAVICON_URI = TEST_SITE + "/browser/browser/components/originattributes/" +
"test/browser/file_favicon.png";
const TEST_THIRD_PARTY_PAGE = "http://example.com/browser/browser/components/" +
"originattributes/test/browser/file_favicon_thirdParty.html";
const THIRD_PARTY_FAVICON_URI = TEST_THIRD_PARTY_SITE + "/browser/browser/components/" +
"originattributes/test/browser/file_favicon.png";
const TEST_PAGE =
TEST_SITE + "/browser/browser/base/content/test/favicons/file_favicon.html";
const FAVICON_URI =
TEST_SITE + "/browser/browser/base/content/test/favicons/file_favicon.png";
const TEST_THIRD_PARTY_PAGE =
TEST_SITE + "/browser/browser/base/content/test/favicons/file_favicon_thirdParty.html";
const THIRD_PARTY_FAVICON_URI =
TEST_THIRD_PARTY_SITE + "/browser/browser/base/content/test/favicons/file_favicon.png";
XPCOMUtils.defineLazyModuleGetter(this, "PromiseUtils",
"resource://gre/modules/PromiseUtils.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "PlacesTestUtils",
"resource://testing-common/PlacesTestUtils.jsm");
let systemPrincipal = Services.scriptSecurityManager.getSystemPrincipal();

View File

@ -0,0 +1,11 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset='utf-8'>
<title>Favicon Test for originAttributes</title>
<link rel="icon" type="image/png" href="file_favicon.png" />
</head>
<body>
Favicon!!
</body>
</html>

Binary file not shown.

After

Width:  |  Height:  |  Size: 344 B

View File

@ -0,0 +1 @@
Cache-Control: no-cache

View File

@ -0,0 +1,11 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset='utf-8'>
<title>Favicon Test for originAttributes</title>
<link rel="icon" type="image/png" href="http://mochi.test:8888/browser/browser/base/content/test/favicons/file_favicon.png" />
</head>
<body>
Third Party Favicon!!
</body>
</html>

View File

@ -14,7 +14,6 @@ support-files =
head.js
[browser_appmenu_reflows.js]
skip-if = asan || debug # Bug 1382809, bug 1369959
[browser_favicon_load.js]
[browser_startup.js]
[browser_startup_content.js]
skip-if = !e10s

View File

@ -50,7 +50,6 @@ DIRS += [
'search',
'sessionstore',
'shell',
'selfsupport',
'syncedtabs',
'uitour',
'translation',

View File

@ -1,77 +0,0 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
const {classes: Cc, interfaces: Ci, utils: Cu} = Components;
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://gre/modules/Services.jsm");
const PREF_FHR_UPLOAD_ENABLED = "datareporting.healthreport.uploadEnabled";
XPCOMUtils.defineLazyModuleGetter(this, "TelemetryArchive",
"resource://gre/modules/TelemetryArchive.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "TelemetryEnvironment",
"resource://gre/modules/TelemetryEnvironment.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "TelemetryController",
"resource://gre/modules/TelemetryController.jsm");
function MozSelfSupportInterface() {
}
MozSelfSupportInterface.prototype = {
classDescription: "MozSelfSupport",
classID: Components.ID("{d30aae8b-f352-4de3-b936-bb9d875df0bb}"),
contractID: "@mozilla.org/mozselfsupport;1",
QueryInterface: XPCOMUtils.generateQI([Ci.nsIDOMGlobalPropertyInitializer]),
_window: null,
init(window) {
this._window = window;
},
get healthReportDataSubmissionEnabled() {
return Services.prefs.getBoolPref(PREF_FHR_UPLOAD_ENABLED, false);
},
set healthReportDataSubmissionEnabled(enabled) {
Services.prefs.setBoolPref(PREF_FHR_UPLOAD_ENABLED, enabled);
},
resetPref(name) {
Services.prefs.clearUserPref(name);
},
resetSearchEngines() {
Services.search.restoreDefaultEngines();
Services.search.resetToOriginalDefaultEngine();
},
getTelemetryPingList() {
return this._wrapPromise(TelemetryArchive.promiseArchivedPingList());
},
getTelemetryPing(pingId) {
return this._wrapPromise(TelemetryArchive.promiseArchivedPingById(pingId));
},
getCurrentTelemetryEnvironment() {
const current = TelemetryEnvironment.currentEnvironment;
return new this._window.Promise(resolve => resolve(current));
},
getCurrentTelemetrySubsessionPing() {
const current = TelemetryController.getCurrentPingData(true);
return new this._window.Promise(resolve => resolve(current));
},
_wrapPromise(promise) {
return new this._window.Promise(
(resolve, reject) => promise.then(resolve, reject));
},
};
this.NSGetFactory = XPCOMUtils.generateNSGetFactory([MozSelfSupportInterface]);

View File

@ -1,2 +0,0 @@
component {d30aae8b-f352-4de3-b936-bb9d875df0bb} SelfSupportService.js
contract @mozilla.org/mozselfsupport;1 {d30aae8b-f352-4de3-b936-bb9d875df0bb}

View File

@ -1,17 +0,0 @@
# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
# vim: set filetype=python:
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
with Files("**"):
BUG_COMPONENT = ("Toolkit", "Telemetry")
EXTRA_COMPONENTS += [
'SelfSupportService.js',
'SelfSupportService.manifest',
]
BROWSER_CHROME_MANIFESTS += [
'test/browser.ini',
]

View File

@ -1,7 +0,0 @@
"use strict";
module.exports = {
"extends": [
"plugin:mozilla/browser-test"
]
};

View File

@ -1,3 +0,0 @@
[DEFAULT]
[browser_selfsupportAPI.js]

View File

@ -1,92 +0,0 @@
function prefHas(pref) {
return Services.prefs.getPrefType(pref) != Ci.nsIPrefBranch.PREF_INVALID;
}
function prefIsSet(pref) {
return Services.prefs.prefHasUserValue(pref);
}
function test_resetPref() {
const prefNewName = "browser.newpref.fake";
Assert.ok(!prefHas(prefNewName), "pref should not exist");
const prefExistingName = "extensions.hotfix.id";
Assert.ok(prefHas(prefExistingName), "pref should exist");
Assert.ok(!prefIsSet(prefExistingName), "pref should not be user-set");
let prefExistingOriginalValue = Services.prefs.getStringPref(prefExistingName);
registerCleanupFunction(function() {
Services.prefs.setStringPref(prefExistingName, prefExistingOriginalValue);
Services.prefs.deleteBranch(prefNewName);
});
// 1. do nothing on an inexistent pref
MozSelfSupport.resetPref(prefNewName);
Assert.ok(!prefHas(prefNewName), "pref should still not exist");
// 2. creation of a new pref
Services.prefs.setIntPref(prefNewName, 10);
Assert.ok(prefHas(prefNewName), "pref should exist");
Assert.equal(Services.prefs.getIntPref(prefNewName), 10, "pref value should be 10");
MozSelfSupport.resetPref(prefNewName);
Assert.ok(!prefHas(prefNewName), "pref should not exist any more");
// 3. do nothing on an unchanged existing pref
MozSelfSupport.resetPref(prefExistingName);
Assert.ok(prefHas(prefExistingName), "pref should still exist");
Assert.equal(Services.prefs.getStringPref(prefExistingName), prefExistingOriginalValue, "pref value should be the same as original");
// 4. change the value of an existing pref
Services.prefs.setStringPref(prefExistingName, "anyone@mozilla.org");
Assert.ok(prefHas(prefExistingName), "pref should exist");
Assert.equal(Services.prefs.getStringPref(prefExistingName), "anyone@mozilla.org", "pref value should have changed");
MozSelfSupport.resetPref(prefExistingName);
Assert.ok(prefHas(prefExistingName), "pref should still exist");
Assert.equal(Services.prefs.getStringPref(prefExistingName), prefExistingOriginalValue, "pref value should be the same as original");
// 5. delete an existing pref
// deleteBranch is implemented in such a way that
// clearUserPref can't undo its action
// see discussion in bug 1075160
}
function test_resetSearchEngines() {
const defaultEngineOriginal = Services.search.defaultEngine;
const visibleEnginesOriginal = Services.search.getVisibleEngines();
// 1. do nothing on unchanged search configuration
MozSelfSupport.resetSearchEngines();
Assert.equal(Services.search.defaultEngine, defaultEngineOriginal, "default engine should be reset");
Assert.deepEqual(Services.search.getVisibleEngines(), visibleEnginesOriginal,
"default visible engines set should be reset");
// 2. change the default search engine
const defaultEngineNew = visibleEnginesOriginal[3];
Assert.notEqual(defaultEngineOriginal, defaultEngineNew, "new default engine should be different from original");
Services.search.defaultEngine = defaultEngineNew;
Assert.equal(Services.search.defaultEngine, defaultEngineNew, "default engine should be set to new");
MozSelfSupport.resetSearchEngines();
Assert.equal(Services.search.defaultEngine, defaultEngineOriginal, "default engine should be reset");
Assert.deepEqual(Services.search.getVisibleEngines(), visibleEnginesOriginal,
"default visible engines set should be reset");
// 3. remove an engine
const engineRemoved = visibleEnginesOriginal[2];
Services.search.removeEngine(engineRemoved);
Assert.ok(Services.search.getVisibleEngines().indexOf(engineRemoved) == -1,
"removed engine should not be visible any more");
MozSelfSupport.resetSearchEngines();
Assert.equal(Services.search.defaultEngine, defaultEngineOriginal, "default engine should be reset");
Assert.deepEqual(Services.search.getVisibleEngines(), visibleEnginesOriginal,
"default visible engines set should be reset");
// 4. add an angine
// we don't remove user-added engines as they are only used if selected
}
function test() {
test_resetPref();
test_resetSearchEngines();
}

View File

@ -490,10 +490,6 @@
@RESPATH@/components/nsINIProcessor.js
@RESPATH@/components/nsPrompter.manifest
@RESPATH@/components/nsPrompter.js
#ifdef MOZ_SERVICES_HEALTHREPORT
@RESPATH@/browser/components/SelfSupportService.manifest
@RESPATH@/browser/components/SelfSupportService.js
#endif
@RESPATH@/components/SyncComponents.manifest
@RESPATH@/components/Weave.js
@RESPATH@/components/FxAccountsComponents.manifest

View File

@ -8,7 +8,7 @@
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<link rel="stylesheet" href="chrome://devtools/skin/widgets.css"/>
<link rel="stylesheet" href="chrome://devtools/skin/breadcrumbs.css"/>
<link rel="stylesheet" href="chrome://devtools/skin/inspector.css"/>
<link rel="stylesheet" href="chrome://devtools/skin/rules.css"/>
<link rel="stylesheet" href="chrome://devtools/skin/computed.css"/>

View File

@ -3442,9 +3442,7 @@ nsDocShell::MaybeCreateInitialClientSource(nsIPrincipal* aPrincipal)
ClientManager::CreateSource(ClientType::Window,
win->EventTargetFor(TaskCategory::Other),
principal);
if (NS_WARN_IF(!mInitialClientSource)) {
return;
}
MOZ_DIAGNOSTIC_ASSERT(mInitialClientSource);
// Mark the initial client as execution ready, but owned by the docshell.
// If the client is actually used this will cause ClientSource to force

View File

@ -235,7 +235,6 @@
#include "mozilla/dom/FunctionBinding.h"
#include "mozilla/dom/HashChangeEvent.h"
#include "mozilla/dom/IntlUtils.h"
#include "mozilla/dom/MozSelfSupportBinding.h"
#include "mozilla/dom/PopStateEvent.h"
#include "mozilla/dom/PopupBlockedEvent.h"
#include "mozilla/dom/PrimitiveConversions.h"
@ -1211,8 +1210,6 @@ nsGlobalWindowInner::CleanUp()
mExternal = nullptr;
mMozSelfSupport = nullptr;
mPerformance = nullptr;
#ifdef MOZ_WEBSPEECH
@ -1508,7 +1505,6 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INTERNAL(nsGlobalWindowInner)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mAudioWorklet)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mPaintWorklet)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mExternal)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mMozSelfSupport)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mIntlUtils)
tmp->TraverseHostObjectURIs(cb);
@ -1586,7 +1582,6 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsGlobalWindowInner)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mAudioWorklet)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mPaintWorklet)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mExternal)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mMozSelfSupport)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mIntlUtils)
tmp->UnlinkHostObjectURIs();
@ -1801,9 +1796,7 @@ nsGlobalWindowInner::EnsureClientSource()
mClientSource = ClientManager::CreateSource(ClientType::Window,
EventTargetFor(TaskCategory::Other),
mDoc->NodePrincipal());
if (NS_WARN_IF(!mClientSource)) {
return NS_ERROR_FAILURE;
}
MOZ_DIAGNOSTIC_ASSERT(mClientSource);
newClientSource = true;
}
@ -1833,9 +1826,7 @@ nsGlobalWindowInner::EnsureClientSource()
ClientManager::CreateSource(ClientType::Window,
EventTargetFor(TaskCategory::Other),
mDoc->NodePrincipal());
if (NS_WARN_IF(!mClientSource)) {
return NS_ERROR_FAILURE;
}
MOZ_DIAGNOSTIC_ASSERT(mClientSource);
newClientSource = true;
}
}
@ -2589,21 +2580,6 @@ nsGlobalWindowInner::GetContent(JSContext* aCx,
(aCx, aRetval, aCallerType, aError), aError, );
}
MozSelfSupport*
nsGlobalWindowInner::GetMozSelfSupport(ErrorResult& aError)
{
if (mMozSelfSupport) {
return mMozSelfSupport;
}
// We're called from JS and want to use out existing JSContext (and,
// importantly, its compartment!) here.
AutoJSContext cx;
GlobalObject global(cx, FastGetGlobalJSObject());
mMozSelfSupport = MozSelfSupport::Constructor(global, cx, aError);
return mMozSelfSupport;
}
BarProp*
nsGlobalWindowInner::GetMenubar(ErrorResult& aError)
{

View File

@ -112,7 +112,6 @@ class IncrementalRunnable;
class IntlUtils;
class Location;
class MediaQueryList;
class MozSelfSupport;
class Navigator;
class OwningExternalOrWindowProxy;
class Promise;
@ -889,8 +888,6 @@ public:
bool ShouldResistFingerprinting();
mozilla::dom::MozSelfSupport* GetMozSelfSupport(mozilla::ErrorResult& aError);
already_AddRefed<nsPIDOMWindowOuter>
OpenDialog(JSContext* aCx,
const nsAString& aUrl,
@ -1326,8 +1323,6 @@ protected:
// it wouldn't see the ~External function's declaration.
nsCOMPtr<nsISupports> mExternal;
RefPtr<mozilla::dom::MozSelfSupport> mMozSelfSupport;
RefPtr<mozilla::dom::Storage> mLocalStorage;
RefPtr<mozilla::dom::Storage> mSessionStorage;

View File

@ -235,7 +235,6 @@
#include "mozilla/dom/FunctionBinding.h"
#include "mozilla/dom/HashChangeEvent.h"
#include "mozilla/dom/IntlUtils.h"
#include "mozilla/dom/MozSelfSupportBinding.h"
#include "mozilla/dom/PopStateEvent.h"
#include "mozilla/dom/PopupBlockedEvent.h"
#include "mozilla/dom/PrimitiveConversions.h"

View File

@ -110,7 +110,6 @@ class IncrementalRunnable;
class IntlUtils;
class Location;
class MediaQueryList;
class MozSelfSupport;
class Navigator;
class OwningExternalOrWindowProxy;
class Promise;

View File

@ -120,6 +120,7 @@ class ClientChannelHelper final : public nsIInterfaceRequestor
reservedClient.reset();
reservedClient = ClientManager::CreateSource(ClientType::Window,
mEventTarget, principal);
MOZ_DIAGNOSTIC_ASSERT(reservedClient);
newLoadInfo->GiveReservedClientSource(Move(reservedClient));
}
@ -228,7 +229,7 @@ AddClientChannelHelper(nsIChannel* aChannel,
reservedClient = ClientManager::CreateSource(ClientType::Window,
aEventTarget,
channelPrincipal);
NS_ENSURE_TRUE(reservedClient, NS_ERROR_FAILURE);
MOZ_DIAGNOSTIC_ASSERT(reservedClient);
}
RefPtr<ClientChannelHelper> helper =

View File

@ -103,18 +103,28 @@ ClientManager::CreateSourceInternal(ClientType aType,
{
NS_ASSERT_OWNINGTHREAD(ClientManager);
if (IsShutdown()) {
return nullptr;
}
nsID id;
nsresult rv = nsContentUtils::GenerateUUIDInPlace(id);
MOZ_DIAGNOSTIC_ASSERT(NS_SUCCEEDED(rv));
if (NS_WARN_IF(NS_FAILED(rv))) {
return nullptr;
// If we can't even get a UUID, at least make sure not to use a garbage
// value. Instead return a shutdown ClientSource with a zero'd id.
// This should be exceptionally rare, if it happens at all.
id.Clear();
ClientSourceConstructorArgs args(id, aType, aPrincipal, TimeStamp::Now());
UniquePtr<ClientSource> source(new ClientSource(this, aEventTarget, args));
source->Shutdown();
return Move(source);
}
ClientSourceConstructorArgs args(id, aType, aPrincipal, TimeStamp::Now());
UniquePtr<ClientSource> source(new ClientSource(this, aEventTarget, args));
if (IsShutdown()) {
source->Shutdown();
return Move(source);
}
source->Activate(GetActor());
return Move(source);
@ -127,12 +137,14 @@ ClientManager::CreateHandleInternal(const ClientInfo& aClientInfo,
NS_ASSERT_OWNINGTHREAD(ClientManager);
MOZ_DIAGNOSTIC_ASSERT(aSerialEventTarget);
if (IsShutdown()) {
return nullptr;
}
RefPtr<ClientHandle> handle = new ClientHandle(this, aSerialEventTarget,
aClientInfo);
if (IsShutdown()) {
handle->Shutdown();
return handle.forget();
}
handle->Activate(GetActor());
return handle.forget();
@ -220,7 +232,7 @@ ClientManager::CreateSource(ClientType aType, nsISerialEventTarget* aEventTarget
PrincipalInfo principalInfo;
nsresult rv = PrincipalToPrincipalInfo(aPrincipal, &principalInfo);
if (NS_WARN_IF(NS_FAILED(rv))) {
return nullptr;
MOZ_CRASH("ClientManager::CreateSource() cannot serialize bad principal");
}
RefPtr<ClientManager> mgr = GetOrCreateForCurrentThread();

View File

@ -24,6 +24,7 @@ using mozilla::ipc::PrincipalInfo;
namespace {
ClientManagerService* sClientManagerServiceInstance = nullptr;
bool sClientManagerServiceShutdownRegistered = false;
bool
MatchPrincipalInfo(const PrincipalInfo& aLeft, const PrincipalInfo& aRight)
@ -146,19 +147,29 @@ ClientManagerService::ClientManagerService()
{
AssertIsOnBackgroundThread();
// While the ClientManagerService will be gracefully terminated as windows
// and workers are naturally killed, this can cause us to do extra work
// relatively late in the shutdown process. To avoid this we eagerly begin
// shutdown at the first sign it has begun. Since we handle normal shutdown
// gracefully we don't really need to block anything here. We just begin
// destroying our IPC actors immediately.
OnShutdown()->Then(GetCurrentThreadSerialEventTarget(), __func__,
[] () {
RefPtr<ClientManagerService> svc = ClientManagerService::GetInstance();
if (svc) {
svc->Shutdown();
}
});
// Only register one shutdown handler at a time. If a previous service
// instance did this, but shutdown has not come, then we can avoid
// doing it again.
if (!sClientManagerServiceShutdownRegistered) {
sClientManagerServiceShutdownRegistered = true;
// While the ClientManagerService will be gracefully terminated as windows
// and workers are naturally killed, this can cause us to do extra work
// relatively late in the shutdown process. To avoid this we eagerly begin
// shutdown at the first sign it has begun. Since we handle normal shutdown
// gracefully we don't really need to block anything here. We just begin
// destroying our IPC actors immediately.
OnShutdown()->Then(GetCurrentThreadSerialEventTarget(), __func__,
[] () {
// Look up the latest service instance, if it exists. This may
// be different from the instance that registered the shutdown
// handler.
RefPtr<ClientManagerService> svc = ClientManagerService::GetInstance();
if (svc) {
svc->Shutdown();
}
});
}
}
ClientManagerService::~ClientManagerService()
@ -175,6 +186,7 @@ void
ClientManagerService::Shutdown()
{
AssertIsOnBackgroundThread();
MOZ_DIAGNOSTIC_ASSERT(sClientManagerServiceShutdownRegistered);
// If many ClientManagerService are created and destroyed quickly we can
// in theory get more than one shutdown listener calling us.

View File

@ -182,6 +182,10 @@ ClientSource::WorkerExecutionReady(WorkerPrivate* aWorkerPrivate)
MOZ_DIAGNOSTIC_ASSERT(aWorkerPrivate);
aWorkerPrivate->AssertIsOnWorkerThread();
if (IsShutdown()) {
return;
}
// Its safe to store the WorkerPrivate* here because the ClientSource
// is explicitly destroyed by WorkerPrivate before exiting its run loop.
MOZ_DIAGNOSTIC_ASSERT(mOwner.is<Nothing>());
@ -202,6 +206,10 @@ ClientSource::WindowExecutionReady(nsPIDOMWindowInner* aInnerWindow)
MOZ_DIAGNOSTIC_ASSERT(aInnerWindow->IsCurrentInnerWindow());
MOZ_DIAGNOSTIC_ASSERT(aInnerWindow->HasActiveDocument());
if (IsShutdown()) {
return NS_OK;
}
nsIDocument* doc = aInnerWindow->GetExtantDoc();
if (NS_WARN_IF(!doc)) {
return NS_ERROR_UNEXPECTED;
@ -253,6 +261,10 @@ ClientSource::DocShellExecutionReady(nsIDocShell* aDocShell)
MOZ_ASSERT(NS_IsMainThread());
MOZ_DIAGNOSTIC_ASSERT(aDocShell);
if (IsShutdown()) {
return NS_OK;
}
nsPIDOMWindowOuter* outer = aDocShell->GetWindow();
if (NS_WARN_IF(!outer)) {
return NS_ERROR_UNEXPECTED;
@ -306,9 +318,15 @@ ClientSource::WorkerSyncPing(WorkerPrivate* aWorkerPrivate)
{
NS_ASSERT_OWNINGTHREAD(ClientSource);
MOZ_DIAGNOSTIC_ASSERT(aWorkerPrivate);
if (IsShutdown()) {
return;
}
MOZ_DIAGNOSTIC_ASSERT(aWorkerPrivate == mManager->GetWorkerPrivate());
aWorkerPrivate->AssertIsOnWorkerThread();
MOZ_DIAGNOSTIC_ASSERT(GetActor());
GetActor()->SendWorkerSyncPing();
}

View File

@ -264,27 +264,6 @@ BuildTransactionHashes(const nsCString& aRpId,
return NS_OK;
}
template<typename T, typename C>
static void
ExecuteCallback(T& aResp, Maybe<nsMainThreadPtrHandle<C>>& aCb)
{
MOZ_ASSERT(NS_IsMainThread());
if (aCb.isNothing()) {
return;
}
// reset callback earlier to allow reentry from callback.
nsMainThreadPtrHandle<C> callback(aCb.ref());
aCb.reset();
MOZ_ASSERT(aCb.isNothing());
MOZ_ASSERT(!!callback);
ErrorResult error;
callback->Call(aResp, error);
NS_WARNING_ASSERTION(!error.Failed(), "dom::U2F::Promise callback failed");
error.SuppressException(); // Useful exceptions already emitted
}
/***********************************************************************
* U2F JavaScript API Implementation
**********************************************************************/
@ -302,9 +281,6 @@ U2F::~U2F()
mChild.swap(c);
c->Disconnect();
}
mRegisterCallback.reset();
mSignCallback.reset();
}
void
@ -337,6 +313,23 @@ U2F::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
return U2FBinding::Wrap(aCx, this, aGivenProto);
}
template<typename T, typename C>
void
U2F::ExecuteCallback(T& aResp, nsMainThreadPtrHandle<C>& aCb)
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(aCb);
// Assert that mTransaction was cleared before before we were called to allow
// reentrancy from microtask checkpoints.
MOZ_ASSERT(mTransaction.isNothing());
ErrorResult error;
aCb->Call(aResp, error);
NS_WARNING_ASSERTION(!error.Failed(), "dom::U2F::Promise callback failed");
error.SuppressException(); // Useful exceptions already emitted
}
void
U2F::Register(const nsAString& aAppId,
const Sequence<RegisterRequest>& aRegisterRequests,
@ -351,12 +344,14 @@ U2F::Register(const nsAString& aAppId,
CancelTransaction(NS_ERROR_ABORT);
}
MOZ_ASSERT(mRegisterCallback.isNothing());
mRegisterCallback = Some(nsMainThreadPtrHandle<U2FRegisterCallback>(
new nsMainThreadPtrHolder<U2FRegisterCallback>(
"U2F::Register::callback", &aCallback)));
nsMainThreadPtrHandle<U2FRegisterCallback> callback(
new nsMainThreadPtrHolder<U2FRegisterCallback>("U2F::Register::callback",
&aCallback));
uint32_t adjustedTimeoutMillis = AdjustedTimeoutMillis(opt_aTimeoutSeconds);
// Ensure we have a callback.
if (NS_WARN_IF(!callback)) {
return;
}
// Evaluate the AppID
nsString adjustedAppId;
@ -365,7 +360,7 @@ U2F::Register(const nsAString& aAppId,
if (appIdResult != ErrorCode::OK) {
RegisterResponse response;
response.mErrorCode.Construct(static_cast<uint32_t>(appIdResult));
ExecuteCallback(response, mRegisterCallback);
ExecuteCallback(response, callback);
return;
}
@ -392,7 +387,7 @@ U2F::Register(const nsAString& aAppId,
if (clientDataJSON.IsEmpty()) {
RegisterResponse response;
response.mErrorCode.Construct(static_cast<uint32_t>(ErrorCode::BAD_REQUEST));
ExecuteCallback(response, mRegisterCallback);
ExecuteCallback(response, callback);
return;
}
@ -408,14 +403,14 @@ U2F::Register(const nsAString& aAppId,
rpIdHash, clientDataHash))) {
RegisterResponse response;
response.mErrorCode.Construct(static_cast<uint32_t>(ErrorCode::OTHER_ERROR));
ExecuteCallback(response, mRegisterCallback);
ExecuteCallback(response, callback);
return;
}
if (!MaybeCreateBackgroundActor()) {
RegisterResponse response;
response.mErrorCode.Construct(static_cast<uint32_t>(ErrorCode::OTHER_ERROR));
ExecuteCallback(response, mRegisterCallback);
ExecuteCallback(response, callback);
return;
}
@ -429,6 +424,8 @@ U2F::Register(const nsAString& aAppId,
false /* requireUserVerification */,
false /* requirePlatformAttachment */);
uint32_t adjustedTimeoutMillis = AdjustedTimeoutMillis(opt_aTimeoutSeconds);
WebAuthnMakeCredentialInfo info(rpIdHash,
clientDataHash,
adjustedTimeoutMillis,
@ -437,7 +434,7 @@ U2F::Register(const nsAString& aAppId,
authSelection);
MOZ_ASSERT(mTransaction.isNothing());
mTransaction = Some(U2FTransaction(clientData));
mTransaction = Some(U2FTransaction(clientData, Move(AsVariant(callback))));
mChild->SendRequestRegister(mTransaction.ref().mId, info);
}
@ -452,6 +449,11 @@ U2F::FinishMakeCredential(const uint64_t& aTransactionId,
return;
}
if (NS_WARN_IF(!mTransaction.ref().HasRegisterCallback())) {
RejectTransaction(NS_ERROR_ABORT);
return;
}
CryptoBuffer clientDataBuf;
if (NS_WARN_IF(!clientDataBuf.Assign(mTransaction.ref().mClientData))) {
RejectTransaction(NS_ERROR_ABORT);
@ -482,8 +484,12 @@ U2F::FinishMakeCredential(const uint64_t& aTransactionId,
response.mRegistrationData.Construct(registrationDataBase64);
response.mErrorCode.Construct(static_cast<uint32_t>(ErrorCode::OK));
ExecuteCallback(response, mRegisterCallback);
// Keep the callback pointer alive.
nsMainThreadPtrHandle<U2FRegisterCallback> callback(
mTransaction.ref().GetRegisterCallback());
ClearTransaction();
ExecuteCallback(response, callback);
}
void
@ -500,12 +506,14 @@ U2F::Sign(const nsAString& aAppId,
CancelTransaction(NS_ERROR_ABORT);
}
MOZ_ASSERT(mSignCallback.isNothing());
mSignCallback = Some(nsMainThreadPtrHandle<U2FSignCallback>(
new nsMainThreadPtrHolder<U2FSignCallback>(
"U2F::Sign::callback", &aCallback)));
nsMainThreadPtrHandle<U2FSignCallback> callback(
new nsMainThreadPtrHolder<U2FSignCallback>("U2F::Sign::callback",
&aCallback));
uint32_t adjustedTimeoutMillis = AdjustedTimeoutMillis(opt_aTimeoutSeconds);
// Ensure we have a callback.
if (NS_WARN_IF(!callback)) {
return;
}
// Evaluate the AppID
nsString adjustedAppId;
@ -514,7 +522,7 @@ U2F::Sign(const nsAString& aAppId,
if (appIdResult != ErrorCode::OK) {
SignResponse response;
response.mErrorCode.Construct(static_cast<uint32_t>(appIdResult));
ExecuteCallback(response, mSignCallback);
ExecuteCallback(response, callback);
return;
}
@ -527,7 +535,7 @@ U2F::Sign(const nsAString& aAppId,
if (NS_WARN_IF(NS_FAILED(rv))) {
SignResponse response;
response.mErrorCode.Construct(static_cast<uint32_t>(ErrorCode::BAD_REQUEST));
ExecuteCallback(response, mSignCallback);
ExecuteCallback(response, callback);
return;
}
@ -543,14 +551,14 @@ U2F::Sign(const nsAString& aAppId,
rpIdHash, clientDataHash))) {
SignResponse response;
response.mErrorCode.Construct(static_cast<uint32_t>(ErrorCode::OTHER_ERROR));
ExecuteCallback(response, mSignCallback);
ExecuteCallback(response, callback);
return;
}
if (!MaybeCreateBackgroundActor()) {
SignResponse response;
response.mErrorCode.Construct(static_cast<uint32_t>(ErrorCode::OTHER_ERROR));
ExecuteCallback(response, mSignCallback);
ExecuteCallback(response, callback);
return;
}
@ -559,6 +567,8 @@ U2F::Sign(const nsAString& aAppId,
// Always blank for U2F
nsTArray<WebAuthnExtension> extensions;
uint32_t adjustedTimeoutMillis = AdjustedTimeoutMillis(opt_aTimeoutSeconds);
WebAuthnGetAssertionInfo info(rpIdHash,
clientDataHash,
adjustedTimeoutMillis,
@ -566,7 +576,7 @@ U2F::Sign(const nsAString& aAppId,
extensions);
MOZ_ASSERT(mTransaction.isNothing());
mTransaction = Some(U2FTransaction(clientData));
mTransaction = Some(U2FTransaction(clientData, Move(AsVariant(callback))));
mChild->SendRequestSign(mTransaction.ref().mId, info);
}
@ -582,6 +592,11 @@ U2F::FinishGetAssertion(const uint64_t& aTransactionId,
return;
}
if (NS_WARN_IF(!mTransaction.ref().HasSignCallback())) {
RejectTransaction(NS_ERROR_ABORT);
return;
}
CryptoBuffer clientDataBuf;
if (NS_WARN_IF(!clientDataBuf.Assign(mTransaction.ref().mClientData))) {
RejectTransaction(NS_ERROR_ABORT);
@ -620,8 +635,12 @@ U2F::FinishGetAssertion(const uint64_t& aTransactionId,
response.mSignatureData.Construct(signatureDataBase64);
response.mErrorCode.Construct(static_cast<uint32_t>(ErrorCode::OK));
ExecuteCallback(response, mSignCallback);
// Keep the callback pointer alive.
nsMainThreadPtrHandle<U2FSignCallback> callback(
mTransaction.ref().GetSignCallback());
ClearTransaction();
ExecuteCallback(response, callback);
}
void
@ -637,23 +656,31 @@ U2F::ClearTransaction()
void
U2F::RejectTransaction(const nsresult& aError)
{
if (!NS_WARN_IF(mTransaction.isNothing())) {
ErrorCode code = ConvertNSResultToErrorCode(aError);
if (mRegisterCallback.isSome()) {
RegisterResponse response;
response.mErrorCode.Construct(static_cast<uint32_t>(code));
ExecuteCallback(response, mRegisterCallback);
}
if (mSignCallback.isSome()) {
SignResponse response;
response.mErrorCode.Construct(static_cast<uint32_t>(code));
ExecuteCallback(response, mSignCallback);
}
if (NS_WARN_IF(mTransaction.isNothing())) {
return;
}
ClearTransaction();
StopListeningForVisibilityEvents();
// Clear out mTransaction before calling ExecuteCallback() below to allow
// reentrancy from microtask checkpoints.
Maybe<U2FTransaction> maybeTransaction(Move(mTransaction));
MOZ_ASSERT(mTransaction.isNothing() && maybeTransaction.isSome());
U2FTransaction& transaction = maybeTransaction.ref();
ErrorCode code = ConvertNSResultToErrorCode(aError);
if (transaction.HasRegisterCallback()) {
RegisterResponse response;
response.mErrorCode.Construct(static_cast<uint32_t>(code));
ExecuteCallback(response, transaction.GetRegisterCallback());
}
if (transaction.HasSignCallback()) {
SignResponse response;
response.mErrorCode.Construct(static_cast<uint32_t>(code));
ExecuteCallback(response, transaction.GetSignCallback());
}
}
void

View File

@ -31,17 +31,41 @@ struct RegisteredKey;
class U2FTransaction
{
typedef Variant<nsMainThreadPtrHandle<U2FRegisterCallback>,
nsMainThreadPtrHandle<U2FSignCallback>> U2FCallback;
public:
explicit U2FTransaction(const nsCString& aClientData)
explicit U2FTransaction(const nsCString& aClientData,
const U2FCallback&& aCallback)
: mClientData(aClientData)
, mCallback(Move(aCallback))
, mId(NextId())
{
MOZ_ASSERT(mId > 0);
}
bool HasRegisterCallback() {
return mCallback.is<nsMainThreadPtrHandle<U2FRegisterCallback>>();
}
auto& GetRegisterCallback() {
return mCallback.as<nsMainThreadPtrHandle<U2FRegisterCallback>>();
}
bool HasSignCallback() {
return mCallback.is<nsMainThreadPtrHandle<U2FSignCallback>>();
}
auto& GetSignCallback() {
return mCallback.as<nsMainThreadPtrHandle<U2FSignCallback>>();
}
// Client data used to assemble reply objects.
nsCString mClientData;
// The callback passed to the API.
U2FCallback mCallback;
// Unique transaction id.
uint64_t mId;
@ -117,17 +141,16 @@ protected:
private:
~U2F();
template<typename T, typename C>
void ExecuteCallback(T& aResp, nsMainThreadPtrHandle<C>& aCb);
// Clears all information we have about the current transaction.
void ClearTransaction();
// Rejects the current transaction and calls ClearTransaction().
// Rejects the current transaction and clears it.
void RejectTransaction(const nsresult& aError);
nsString mOrigin;
// U2F API callbacks.
Maybe<nsMainThreadPtrHandle<U2FRegisterCallback>> mRegisterCallback;
Maybe<nsMainThreadPtrHandle<U2FSignCallback>> mSignCallback;
// The current transaction, if any.
Maybe<U2FTransaction> mTransaction;
};

View File

@ -1,77 +0,0 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/**
* The MozSelfSupport interface allows external Mozilla support sites such as
* FHR and SUMO to access data and control settings that are not otherwise
* exposed to external content.
*
* At the moment, this is a ChromeOnly interface, but the plan is to allow
* specific Mozilla domains to access it directly.
*/
[ChromeOnly,
JSImplementation="@mozilla.org/mozselfsupport;1",
Constructor()]
interface MozSelfSupport
{
/**
* Controls whether uploading FHR data is allowed.
*/
attribute boolean healthReportDataSubmissionEnabled;
/**
* Retrieve a list of the archived Telemetry pings.
* This contains objects with ping info, which are of the form:
* {
* type: <string>, // The pings type, e.g. "main", "environment-change", ...
* timestampCreated: <number>, // The time the ping was created (ms since unix epoch).
* id: <string>, // The pings UUID.
* }
*
* @return Promise<sequence<Object>>
* Resolved with the ping infos when the archived ping list has been built.
*/
Promise<sequence<object>> getTelemetryPingList();
/**
* Retrieve an archived Telemetry ping by it's id.
* This will load the ping data async from the archive, possibly hitting the disk.
*
* @return Promise<Object>
* Resolved with the ping data, see the Telemetry "main" ping documentation for the format.
*/
Promise<object> getTelemetryPing(DOMString pingID);
/**
* Get the current Telemetry environment - see the Telemetry documentation for details on the format.
*
* @return Promise<Object>
* Resolved with an object containing the Telemetry environment data.
*/
Promise<object> getCurrentTelemetryEnvironment();
/**
* Get a Telemetry "main" ping containing the current session measurements.
*
* @return Promise<Object>
* Resolved with the ping data, see the Telemetry "main" ping documentation for the format.
*/
Promise<object> getCurrentTelemetrySubsessionPing();
/**
* Resets a named pref:
* - if there is a default value, then change the value back to default,
* - if there's no default value, then delete the pref,
* - no-op otherwise.
*
* @param DOMString
* The name of the pref to reset.
*/
void resetPref(DOMString name);
/**
* Resets original search engines, and resets the default one.
*/
void resetSearchEngines();
};

View File

@ -303,14 +303,6 @@ partial interface Window {
*/
[Throws] readonly attribute unsigned long long mozPaintCount;
/**
* This property exists because static attributes don't yet work for
* JS-implemented WebIDL (see bugs 1058606 and 863952). With this hack, we
* can use `MozSelfSupport.something(...)`, which will continue to work
* after we ditch this property and switch to static attributes. See
*/
[ChromeOnly, Throws] readonly attribute MozSelfSupport MozSelfSupport;
attribute EventHandler ondevicemotion;
attribute EventHandler ondeviceorientation;
attribute EventHandler onabsolutedeviceorientation;

View File

@ -214,9 +214,6 @@ with Files("Media*Track*"):
with Files("Mouse*"):
BUG_COMPONENT = ("Core", "DOM: Events")
with Files("MozSelfSupport.webidl"):
BUG_COMPONENT = ("Firefox Health Report", "Client: Desktop")
with Files("MozTimeManager.webidl"):
BUG_COMPONENT = ("Core", "DOM: Device Interfaces")
@ -693,7 +690,6 @@ WEBIDL_FILES = [
'MimeTypeArray.webidl',
'MouseEvent.webidl',
'MouseScrollEvent.webidl',
'MozSelfSupport.webidl',
'MozStorageAsyncStatementParams.webidl',
'MozStorageStatementParams.webidl',
'MozStorageStatementRow.webidl',

View File

@ -2376,9 +2376,7 @@ ServiceWorkerManager::StartControllingADocument(ServiceWorkerRegistrationInfo* a
RefPtr<ClientHandle> clientHandle =
ClientManager::CreateHandle(clientInfo.ref(),
SystemGroup::EventTargetFor(TaskCategory::Other));
if (clientHandle) {
ref = Move(clientHandle->Control(activeWorker->Descriptor()));
}
ref = Move(clientHandle->Control(activeWorker->Descriptor()));
}
}
@ -2724,9 +2722,7 @@ ServiceWorkerManager::DispatchFetchEvent(const OriginAttributes& aOriginAttribut
RefPtr<ClientHandle> clientHandle =
ClientManager::CreateHandle(clientInfo.ref(),
SystemGroup::EventTargetFor(TaskCategory::Other));
if (clientHandle) {
clientHandle->Control(serviceWorker->Descriptor());
}
clientHandle->Control(serviceWorker->Descriptor());
}
// But we also note the reserved state on the LoadInfo. This allows the

View File

@ -5332,9 +5332,7 @@ WorkerPrivate::EnsureClientSource()
mClientSource = ClientManager::CreateSource(type, mWorkerHybridEventTarget,
GetPrincipalInfo());
if (!mClientSource) {
return false;
}
MOZ_DIAGNOSTIC_ASSERT(mClientSource);
if (mFrozen) {
mClientSource->Freeze();

View File

@ -1,4 +1,4 @@
52460
52463
0/nm
0th/pt
1/n1
@ -5795,7 +5795,7 @@ IRS/M
ISBN
ISIS
ISO/M
ISP
ISP/SM
ISS
IT
IUD
@ -25844,6 +25844,7 @@ fearful/YP
fearfulness/M
fearless/PY
fearlessness/M
fearmonger/SMG
fearsome
feasibility/M
feasible/IU
@ -40309,7 +40310,7 @@ prepacked
prepaid
preparation/SM
preparatory
prepare/GDS
prepare/GDSRZ
prepared/UP
preparedness/UM
prepay/GSL
@ -40861,6 +40862,7 @@ prudish/YP
prudishness/M
prune/MZGDRS
pruner/M
pruno
prurience/M
prurient/Y
pry/ZTGDRSM
@ -49289,6 +49291,7 @@ treatise/SM
treatment/MS
treaty/SM
treble/MGDS
trebuchet/S
tree/MDS
treeing
treeless

View File

@ -391,10 +391,7 @@ PaintThread::AsyncPaintTiledContents(CompositorBridgeChild* aBridge,
// Draw all the things into the actual dest target.
target->DrawCapturedDT(capture, Matrix());
if (!mDrawTargetsToFlush.Contains(target)) {
mDrawTargetsToFlush.AppendElement(target);
}
target->Flush();
if (gfxPrefs::LayersOMTPReleaseCaptureOnMainThread()) {
// This should ensure the capture drawtarget, which may hold on to UnscaledFont objects,

View File

@ -987,6 +987,8 @@ extern bool gfx_use_wrench();
extern const char *gfx_wr_resource_path_override();
extern bool is_glcontext_angle(void *aGlcontextPtr);
extern bool is_glcontext_egl(void *aGlcontextPtr);
extern bool is_in_compositor_thread();

View File

@ -317,21 +317,13 @@ IndirectBindingMap::Binding::Binding(ModuleEnvironmentObject* environment, Shape
: environment(environment), shape(shape)
{}
IndirectBindingMap::IndirectBindingMap(Zone* zone)
: map_(ZoneAllocPolicy(zone))
{
}
bool
IndirectBindingMap::init()
{
return map_.init();
}
void
IndirectBindingMap::trace(JSTracer* trc)
{
for (Map::Enum e(map_); !e.empty(); e.popFront()) {
if (!map_)
return;
for (Map::Enum e(*map_); !e.empty(); e.popFront()) {
Binding& b = e.front().value();
TraceEdge(trc, &b.environment, "module bindings environment");
TraceEdge(trc, &b.shape, "module bindings shape");
@ -345,9 +337,22 @@ bool
IndirectBindingMap::put(JSContext* cx, HandleId name,
HandleModuleEnvironmentObject environment, HandleId localName)
{
// This object might have been allocated on the background parsing thread in
// different zone to the final module. Lazily allocate the map so we don't
// have to switch its zone when merging compartments.
if (!map_) {
MOZ_ASSERT(!cx->zone()->group()->createdForHelperThread());
map_.emplace(cx->zone());
if (!map_->init()) {
map_.reset();
ReportOutOfMemory(cx);
return false;
}
}
RootedShape shape(cx, environment->lookup(cx, localName));
MOZ_ASSERT(shape);
if (!map_.put(name, Binding(environment, shape))) {
if (!map_->put(name, Binding(environment, shape))) {
ReportOutOfMemory(cx);
return false;
}
@ -358,7 +363,10 @@ IndirectBindingMap::put(JSContext* cx, HandleId name,
bool
IndirectBindingMap::lookup(jsid name, ModuleEnvironmentObject** envOut, Shape** shapeOut) const
{
auto ptr = map_.lookup(name);
if (!map_)
return false;
auto ptr = map_->lookup(name);
if (!ptr)
return false;
@ -759,10 +767,9 @@ ModuleObject::create(JSContext* cx)
RootedModuleObject self(cx, &obj->as<ModuleObject>());
Zone* zone = cx->zone();
IndirectBindingMap* bindings = zone->new_<IndirectBindingMap>(zone);
if (!bindings || !bindings->init()) {
IndirectBindingMap* bindings = zone->new_<IndirectBindingMap>();
if (!bindings) {
ReportOutOfMemory(cx);
js_delete<IndirectBindingMap>(bindings);
return nullptr;
}
@ -1105,8 +1112,8 @@ ModuleObject::createNamespace(JSContext* cx, HandleModuleObject self, HandleObje
MOZ_ASSERT(exports->is<ArrayObject>());
Zone* zone = cx->zone();
auto bindings = zone->make_unique<IndirectBindingMap>(zone);
if (!bindings || !bindings->init()) {
auto bindings = zone->make_unique<IndirectBindingMap>();
if (!bindings) {
ReportOutOfMemory(cx);
return nullptr;
}

View File

@ -7,6 +7,8 @@
#ifndef builtin_ModuleObject_h
#define builtin_ModuleObject_h
#include "mozilla/Maybe.h"
#include "jsapi.h"
#include "jsatom.h"
@ -128,27 +130,27 @@ typedef Handle<RequestedModuleObject*> HandleRequestedModuleObject;
class IndirectBindingMap
{
public:
explicit IndirectBindingMap(Zone* zone);
bool init();
void trace(JSTracer* trc);
bool put(JSContext* cx, HandleId name,
HandleModuleEnvironmentObject environment, HandleId localName);
size_t count() const {
return map_.count();
return map_ ? map_->count() : 0;
}
bool has(jsid name) const {
return map_.has(name);
return map_ ? map_->has(name) : false;
}
bool lookup(jsid name, ModuleEnvironmentObject** envOut, Shape** shapeOut) const;
template <typename Func>
void forEachExportedName(Func func) const {
for (auto r = map_.all(); !r.empty(); r.popFront())
if (!map_)
return;
for (auto r = map_->all(); !r.empty(); r.popFront())
func(r.front().key());
}
@ -162,7 +164,7 @@ class IndirectBindingMap
typedef HashMap<jsid, Binding, DefaultHasher<jsid>, ZoneAllocPolicy> Map;
Map map_;
mozilla::Maybe<Map> map_;
};
class ModuleNamespaceObject : public ProxyObject

View File

@ -0,0 +1,28 @@
if (helperThreadCount() == 0)
quit();
// Overwrite built-in parseModule with off-thread module parser.
function parseModule(source) {
offThreadCompileModule(source);
return finishOffThreadModule();
}
// Test case derived from: js/src/jit-test/tests/modules/many-imports.js
// Test importing an import many times.
load(libdir + "dummyModuleResolveHook.js");
const count = 1024;
let a = moduleRepo['a'] = parseModule("export let a = 1;");
let s = "";
for (let i = 0; i < count; i++) {
s += "import { a as i" + i + " } from 'a';\n";
s += "assertEq(i" + i + ", 1);\n";
}
let b = moduleRepo['b'] = parseModule(s);
b.declarationInstantiation();
b.evaluation();

View File

@ -1929,8 +1929,11 @@ TryAttachFunCallStub(JSContext* cx, ICCall_Fallback* stub, HandleScript script,
static bool
GetTemplateObjectForSimd(JSContext* cx, JSFunction* target, MutableHandleObject res)
{
if (!target->hasJitInfo())
return false;
const JSJitInfo* jitInfo = target->jitInfo();
if (!jitInfo || jitInfo->type() != JSJitInfo::InlinableNative)
if (jitInfo->type() != JSJitInfo::InlinableNative)
return false;
// Check if this is a native inlinable SIMD operation.
@ -2370,11 +2373,10 @@ TryAttachCallStub(JSContext* cx, ICCall_Fallback* stub, HandleScript script, jsb
MOZ_ASSERT_IF(templateObject, !templateObject->group()->maybePreliminaryObjects());
}
bool ignoresReturnValue = false;
if (op == JSOP_CALL_IGNORES_RV && fun->isNative()) {
const JSJitInfo* jitInfo = fun->jitInfo();
ignoresReturnValue = jitInfo && jitInfo->type() == JSJitInfo::IgnoresReturnValueNative;
}
bool ignoresReturnValue = op == JSOP_CALL_IGNORES_RV &&
fun->isNative() &&
fun->hasJitInfo() &&
fun->jitInfo()->type() == JSJitInfo::IgnoresReturnValueNative;
JitSpew(JitSpew_BaselineIC, " Generating Call_Native stub (fun=%p, cons=%s, spread=%s)",
fun.get(), constructing ? "yes" : "no", isSpread ? "yes" : "no");
@ -3554,6 +3556,7 @@ ICCall_Native::Compiler::generateStubCode(MacroAssembler& masm)
masm.callWithABI(Address(ICStubReg, ICCall_Native::offsetOfNative()));
#else
if (ignoresReturnValue_) {
MOZ_ASSERT(callee_->hasJitInfo());
masm.loadPtr(Address(callee, JSFunction::offsetOfJitInfo()), callee);
masm.callWithABI(Address(callee, JSJitInfo::offsetOfIgnoresReturnValueNative()));
} else {

View File

@ -347,7 +347,7 @@ IsCacheableGetPropCallNative(JSObject* obj, JSObject* holder, Shape* shape)
// Check for a getter that has jitinfo and whose jitinfo says it's
// OK with both inner and outer objects.
if (getter.jitInfo() && !getter.jitInfo()->needsOuterizedThisObject())
if (getter.hasJitInfo() && !getter.jitInfo()->needsOuterizedThisObject())
return true;
// For getters that need the WindowProxy (instead of the Window) as this
@ -849,7 +849,7 @@ GetPropIRGenerator::tryAttachWindowProxy(HandleObject obj, ObjOperandId objId, H
// instead of the WindowProxy as |this| value.
JSFunction* callee = &shape->getterObject()->as<JSFunction>();
MOZ_ASSERT(callee->isNative());
if (!callee->jitInfo() || callee->jitInfo()->needsOuterizedThisObject())
if (!callee->hasJitInfo() || callee->jitInfo()->needsOuterizedThisObject())
return false;
// If a |super| access, it is not worth the complexity to attach an IC.
@ -3165,7 +3165,7 @@ IsCacheableSetPropCallNative(JSObject* obj, JSObject* holder, Shape* shape)
if (setter.isClassConstructor())
return false;
if (setter.jitInfo() && !setter.jitInfo()->needsOuterizedThisObject())
if (setter.hasJitInfo() && !setter.jitInfo()->needsOuterizedThisObject())
return true;
return !IsWindow(obj);

View File

@ -4053,9 +4053,9 @@ CodeGenerator::visitCallNative(LCallNative* call)
masm.passABIArg(argUintNReg);
masm.passABIArg(argVpReg);
JSNative native = target->native();
if (call->ignoresReturnValue()) {
if (call->ignoresReturnValue() && target->hasJitInfo()) {
const JSJitInfo* jitInfo = target->jitInfo();
if (jitInfo && jitInfo->type() == JSJitInfo::IgnoresReturnValueNative)
if (jitInfo->type() == JSJitInfo::IgnoresReturnValueNative)
native = jitInfo->ignoresReturnValueMethod;
}
masm.callWithABI(JS_FUNC_TO_DATA_PTR(void*, native), MoveOp::GENERAL,
@ -4110,7 +4110,7 @@ CodeGenerator::visitCallDOMNative(LCallDOMNative* call)
WrappedFunction* target = call->getSingleTarget();
MOZ_ASSERT(target);
MOZ_ASSERT(target->isNative());
MOZ_ASSERT(target->jitInfo());
MOZ_ASSERT(target->hasJitInfo());
MOZ_ASSERT(call->mir()->isCallDOMNative());
int callargslot = call->argslot();

View File

@ -3750,7 +3750,7 @@ IonBuilder::inlineScriptedCall(CallInfo& callInfo, JSFunction* target)
}
// Capture formals in the outer resume point.
MOZ_TRY(callInfo.pushFormals(this, current));
MOZ_TRY(callInfo.pushCallStack(this, current));
MResumePoint* outerResumePoint =
MResumePoint::New(alloc(), current, pc, MResumePoint::Outer);
@ -3759,7 +3759,7 @@ IonBuilder::inlineScriptedCall(CallInfo& callInfo, JSFunction* target)
current->setOuterResumePoint(outerResumePoint);
// Pop formals again, except leave |fun| on stack for duration of call.
callInfo.popFormals(current);
callInfo.popCallStack(current);
current->push(callInfo.fun());
JSScript* calleeScript = target->nonLazyScript();
@ -4416,7 +4416,7 @@ IonBuilder::inlineGenericFallback(JSFunction* target, CallInfo& callInfo, MBasic
CallInfo fallbackInfo(alloc(), pc, callInfo.constructing(), callInfo.ignoresReturnValue());
if (!fallbackInfo.init(callInfo))
return abort(AbortReason::Alloc);
fallbackInfo.popFormals(fallbackBlock);
fallbackInfo.popCallStack(fallbackBlock);
// Generate an MCall, which uses stateful |current|.
MOZ_TRY(setCurrentAndSpecializePhis(fallbackBlock));
@ -4473,7 +4473,7 @@ IonBuilder::inlineObjectGroupFallback(CallInfo& callInfo, MBasicBlock* dispatchB
MBasicBlock* prepBlock;
MOZ_TRY_VAR(prepBlock, newBlock(dispatchBlock, pc));
graph().addBlock(prepBlock);
fallbackInfo.popFormals(prepBlock);
fallbackInfo.popCallStack(prepBlock);
// Construct a block into which the MGetPropertyCache can be moved.
// This is subtle: the pc and resume point are those of the MGetPropertyCache!
@ -4536,7 +4536,7 @@ IonBuilder::inlineCalls(CallInfo& callInfo, const InliningTargets& targets, Bool
MBasicBlock* dispatchBlock = current;
callInfo.setImplicitlyUsedUnchecked();
MOZ_TRY(callInfo.pushFormals(this, dispatchBlock));
MOZ_TRY(callInfo.pushCallStack(this, dispatchBlock));
// Patch any InlinePropertyTable to only contain functions that are
// inlineable. The InlinePropertyTable will also be patched at the end to
@ -4569,7 +4569,7 @@ IonBuilder::inlineCalls(CallInfo& callInfo, const InliningTargets& targets, Bool
// Set up stack, used to manually create a post-call resume point.
returnBlock->inheritSlots(dispatchBlock);
callInfo.popFormals(returnBlock);
callInfo.popCallStack(returnBlock);
MPhi* retPhi = MPhi::New(alloc());
returnBlock->addPhi(retPhi);
@ -4632,7 +4632,7 @@ IonBuilder::inlineCalls(CallInfo& callInfo, const InliningTargets& targets, Bool
CallInfo inlineInfo(alloc(), pc, callInfo.constructing(), callInfo.ignoresReturnValue());
if (!inlineInfo.init(callInfo))
return abort(AbortReason::Alloc);
inlineInfo.popFormals(inlineBlock);
inlineInfo.popCallStack(inlineBlock);
inlineInfo.setFun(funcDef);
if (maybeCache) {
@ -5264,6 +5264,20 @@ IonBuilder::jsop_funapplyarray(uint32_t argc)
return pushTypeBarrier(apply, types, BarrierKind::TypeSet);
}
AbortReasonOr<Ok>
CallInfo::savePriorCallStack(MIRGenerator* mir, MBasicBlock* current, size_t peekDepth)
{
MOZ_ASSERT(priorArgs_.empty());
if (!priorArgs_.reserve(peekDepth))
return mir->abort(AbortReason::Alloc);
while (peekDepth) {
priorArgs_.infallibleAppend(current->peek(0 - int32_t(peekDepth)));
peekDepth--;
}
return Ok();
}
AbortReasonOr<Ok>
IonBuilder::jsop_funapplyarguments(uint32_t argc)
{
@ -5319,6 +5333,7 @@ IonBuilder::jsop_funapplyarguments(uint32_t argc)
CallInfo callInfo(alloc(), pc, /* constructing = */ false,
/* ignoresReturnValue = */ BytecodeIsPopped(pc));
MOZ_TRY(callInfo.savePriorCallStack(this, current, 4));
// Vp
MDefinition* vp = current->pop();
@ -5420,7 +5435,7 @@ IonBuilder::jsop_call(uint32_t argc, bool constructing, bool ignoresReturnValue)
AbortReasonOr<bool>
IonBuilder::testShouldDOMCall(TypeSet* inTypes, JSFunction* func, JSJitInfo::OpType opType)
{
if (!func->isNative() || !func->jitInfo())
if (!func->isNative() || !func->hasJitInfo())
return false;
// If all the DOM objects flowing through are legal with this
@ -7191,7 +7206,7 @@ IonBuilder::addTypeBarrier(MDefinition* def, TemporaryTypeSet* observed, Barrier
AbortReasonOr<Ok>
IonBuilder::pushDOMTypeBarrier(MInstruction* ins, TemporaryTypeSet* observed, JSFunction* func)
{
MOZ_ASSERT(func && func->isNative() && func->jitInfo());
MOZ_ASSERT(func && func->isNative() && func->hasJitInfo());
const JSJitInfo* jitinfo = func->jitInfo();
bool barrier = DOMCallNeedsBarrier(jitinfo, observed);

View File

@ -1192,6 +1192,9 @@ class CallInfo
MDefinition* thisArg_;
MDefinition* newTargetArg_;
MDefinitionVector args_;
// If non-empty, this corresponds to the stack prior any implicit inlining
// such as before JSOP_FUNAPPLY.
MDefinitionVector priorArgs_;
bool constructing_:1;
@ -1207,6 +1210,7 @@ class CallInfo
thisArg_(nullptr),
newTargetArg_(nullptr),
args_(alloc),
priorArgs_(alloc),
constructing_(constructing),
ignoresReturnValue_(ignoresReturnValue),
setter_(false),
@ -1250,11 +1254,30 @@ class CallInfo
return true;
}
void popFormals(MBasicBlock* current) {
// Before doing any pop to the stack, capture whatever flows into the
// instruction, such that we can restore it later.
AbortReasonOr<Ok> savePriorCallStack(MIRGenerator* mir, MBasicBlock* current, size_t peekDepth);
void popPriorCallStack(MBasicBlock* current) {
if (priorArgs_.empty())
popCallStack(current);
else
current->popn(priorArgs_.length());
}
AbortReasonOr<Ok> pushPriorCallStack(MIRGenerator* mir, MBasicBlock* current) {
if (priorArgs_.empty())
return pushCallStack(mir, current);
for (MDefinition* def : priorArgs_)
current->push(def);
return Ok();
}
void popCallStack(MBasicBlock* current) {
current->popn(numFormals());
}
AbortReasonOr<Ok> pushFormals(MIRGenerator* mir, MBasicBlock* current) {
AbortReasonOr<Ok> pushCallStack(MIRGenerator* mir, MBasicBlock* current) {
// Ensure sufficient space in the slots: needed for inlining from FUNAPPLY.
if (apply_) {
uint32_t depth = current->stackDepth() + numFormals();

View File

@ -55,7 +55,7 @@ IonBuilder::inlineNativeCall(CallInfo& callInfo, JSFunction* target)
return InliningStatus_NotInlined;
}
if (!target->jitInfo() || target->jitInfo()->type() != JSJitInfo::InlinableNative) {
if (!target->hasJitInfo() || target->jitInfo()->type() != JSJitInfo::InlinableNative) {
// Reaching here means we tried to inline a native for which there is no
// Ion specialization.
trackOptimizationOutcome(TrackedOutcome::CantInlineNativeNoSpecialization);
@ -846,7 +846,7 @@ IonBuilder::inlineArrayPush(CallInfo& callInfo)
// Restore the stack, such that resume points are created with the stack
// as it was before the call.
MOZ_TRY(callInfo.pushFormals(this, current));
MOZ_TRY(callInfo.pushPriorCallStack(this, current));
}
MInstruction* ins = nullptr;
@ -879,7 +879,7 @@ IonBuilder::inlineArrayPush(CallInfo& callInfo)
if (callInfo.argc() > 1) {
// Fix the stack to represent the state after the call execution.
callInfo.popFormals(current);
callInfo.popPriorCallStack(current);
}
current->push(ins);

View File

@ -2159,12 +2159,10 @@ MCallDOMNative::congruentTo(const MDefinition* ins) const
const JSJitInfo*
MCallDOMNative::getJitInfo() const
{
MOZ_ASSERT(getSingleTarget() && getSingleTarget()->isNative());
const JSJitInfo* jitInfo = getSingleTarget()->jitInfo();
MOZ_ASSERT(jitInfo);
return jitInfo;
MOZ_ASSERT(getSingleTarget() &&
getSingleTarget()->isNative() &&
getSingleTarget()->hasJitInfo());
return getSingleTarget()->jitInfo();
}
MDefinition*

View File

@ -4147,7 +4147,6 @@ class MInitElemGetterSetter
INSTRUCTION_HEADER(InitElemGetterSetter)
TRIVIAL_NEW_WRAPPERS
NAMED_OPERANDS((0, object), (1, idValue), (2, value))
};
// WrappedFunction wraps a JSFunction so it can safely be used off-thread.
@ -4174,6 +4173,7 @@ class WrappedFunction : public TempObject
// fun->native() and fun->jitInfo() can safely be called off-thread: these
// fields never change.
JSNative native() const { return fun_->native(); }
bool hasJitInfo() const { return fun_->hasJitInfo(); }
const JSJitInfo* jitInfo() const { return fun_->jitInfo(); }
JSFunction* rawJSFunction() const { return fun_; }

View File

@ -471,8 +471,10 @@ MacroAssembler::branchIfFunctionHasNoScript(Register fun, Label* label)
{
// 16-bit loads are slow and unaligned 32-bit loads may be too so
// perform an aligned 32-bit load and adjust the bitmask accordingly.
MOZ_ASSERT(JSFunction::offsetOfNargs() % sizeof(uint32_t) == 0);
MOZ_ASSERT(JSFunction::offsetOfFlags() == JSFunction::offsetOfNargs() + 2);
static_assert(JSFunction::offsetOfNargs() % sizeof(uint32_t) == 0,
"The code in this function and the ones below must change");
static_assert(JSFunction::offsetOfFlags() == JSFunction::offsetOfNargs() + 2,
"The code in this function and the ones below must change");
Address address(fun, JSFunction::offsetOfNargs());
int32_t bit = IMM32_16ADJ(JSFunction::INTERPRETED);
branchTest32(Assembler::Zero, address, Imm32(bit), label);
@ -483,8 +485,6 @@ MacroAssembler::branchIfInterpreted(Register fun, Label* label)
{
// 16-bit loads are slow and unaligned 32-bit loads may be too so
// perform an aligned 32-bit load and adjust the bitmask accordingly.
MOZ_ASSERT(JSFunction::offsetOfNargs() % sizeof(uint32_t) == 0);
MOZ_ASSERT(JSFunction::offsetOfFlags() == JSFunction::offsetOfNargs() + 2);
Address address(fun, JSFunction::offsetOfNargs());
int32_t bit = IMM32_16ADJ(JSFunction::INTERPRETED);
branchTest32(Assembler::NonZero, address, Imm32(bit), label);

View File

@ -238,13 +238,11 @@ class FloatRegisters {
static const uint32_t TotalPhys = 8;
static const uint32_t Allocatable = 7;
typedef uint32_t SetType;
#elif defined(JS_CODEGEN_X64)
static const uint32_t Total = 16 * NumTypes;
static const uint32_t TotalPhys = 16;
static const uint32_t Allocatable = 15;
typedef uint64_t SetType;
#endif
static_assert(sizeof(SetType) * 8 >= Total,
@ -285,7 +283,6 @@ class FloatRegisters {
(1 << X86Encoding::xmm5)
) * SpreadScalar
| AllPhysMask * SpreadVector;
#else
static const SetType VolatileMask =
AllMask;

View File

@ -77,7 +77,6 @@ class ABIArgGenerator
ABIArg next(MIRType argType);
ABIArg& current() { return current_; }
uint32_t stackBytesConsumedSoFar() const { return stackOffset_; }
};
// These registers may be volatile or nonvolatile.

View File

@ -2234,7 +2234,7 @@ js::CloneAsmJSModuleFunction(JSContext* cx, HandleFunction fun)
return nullptr;
MOZ_ASSERT(fun->native() == InstantiateAsmJS);
MOZ_ASSERT(!fun->jitInfo());
MOZ_ASSERT(!fun->hasJitInfo());
clone->initNative(InstantiateAsmJS, nullptr);
clone->setGroup(fun->group());
@ -2254,7 +2254,7 @@ js::CloneSelfHostingIntrinsic(JSContext* cx, HandleFunction fun)
if (!clone)
return nullptr;
clone->initNative(fun->native(), fun->jitInfo());
clone->initNative(fun->native(), fun->hasJitInfo() ? fun->jitInfo() : nullptr);
return clone;
}

View File

@ -58,6 +58,7 @@ class JSFunction : public js::NativeObject
CONSTRUCTOR = 0x0002, /* function that can be called as a constructor */
EXTENDED = 0x0004, /* structure is FunctionExtended */
BOUND_FUN = 0x0008, /* function was created with Function.prototype.bind. */
WASM_OPTIMIZED = 0x0010, /* asm.js/wasm function that has a jit entry */
HAS_GUESSED_ATOM = 0x0020, /* function had no explicit name, but a
name was guessed for it anyway */
HAS_BOUND_FUNCTION_NAME_PREFIX = 0x0020, /* bound functions reuse the HAS_GUESSED_ATOM
@ -90,7 +91,9 @@ class JSFunction : public js::NativeObject
NATIVE_CTOR = NATIVE_FUN | CONSTRUCTOR,
NATIVE_CLASS_CTOR = NATIVE_FUN | CONSTRUCTOR | CLASSCONSTRUCTOR_KIND,
ASMJS_CTOR = ASMJS_KIND | NATIVE_CTOR,
ASMJS_OPT_CTOR = ASMJS_CTOR | WASM_OPTIMIZED,
ASMJS_LAMBDA_CTOR = ASMJS_KIND | NATIVE_CTOR | LAMBDA,
WASM_FUN = NATIVE_FUN | WASM_OPTIMIZED,
INTERPRETED_METHOD = INTERPRETED | METHOD_KIND,
INTERPRETED_METHOD_GENERATOR_OR_ASYNC = INTERPRETED | METHOD_KIND,
INTERPRETED_CLASS_CONSTRUCTOR = INTERPRETED | CLASSCONSTRUCTOR_KIND | CONSTRUCTOR,
@ -131,6 +134,11 @@ class JSFunction : public js::NativeObject
js::LazyScript* lazy_; /* lazily compiled script, or nullptr */
} s;
} scripted;
class {
friend class JSFunction;
js::Native native_; // The native for interpreter wasm calls.
void* jitEntry_; // A pointer to a fast jit->wasm table entry.
} wasm;
} u;
js::GCPtrAtom atom_; /* name for diagnostics and decompiling */
@ -185,6 +193,13 @@ class JSFunction : public js::NativeObject
/* Possible attributes of a native function: */
bool isAsmJSNative() const { return kind() == AsmJS; }
bool isWasmOptimized() const { return (flags() & WASM_OPTIMIZED); }
bool isBuiltinNative() const { return isNative() && !isAsmJSNative() && !isWasmOptimized(); }
// May be called from the JIT with the jitEntry_ field.
bool isNativeWithJitEntry() const { return isNative() && isWasmOptimized(); }
// Must be called from the JIT with the native_ field.
bool isNativeWithCppEntry() const { return isNative() && !isWasmOptimized(); }
/* Possible attributes of an interpreted function: */
bool isBoundFunction() const { return flags() & BOUND_FUN; }
@ -235,7 +250,7 @@ class JSFunction : public js::NativeObject
/* Compound attributes: */
bool isBuiltin() const {
return (isNative() && !isAsmJSNative()) || isSelfHostedBuiltin();
return isBuiltinNative() || isSelfHostedBuiltin();
}
bool isNamedLambda() const {
@ -569,27 +584,46 @@ class JSFunction : public js::NativeObject
}
void initNative(js::Native native, const JSJitInfo* jitinfo) {
MOZ_ASSERT(isNativeWithCppEntry());
MOZ_ASSERT(native);
u.native.func_ = native;
u.native.jitinfo_ = jitinfo;
}
bool hasJitInfo() const {
return isNativeWithCppEntry() && u.native.jitinfo_;
}
const JSJitInfo* jitInfo() const {
MOZ_ASSERT(isNative());
MOZ_ASSERT(hasJitInfo());
return u.native.jitinfo_;
}
void setJitInfo(const JSJitInfo* data) {
MOZ_ASSERT(isNative());
MOZ_ASSERT(isNativeWithCppEntry());
u.native.jitinfo_ = data;
}
void initWasmNative(js::Native native) {
MOZ_ASSERT(isNativeWithJitEntry());
MOZ_ASSERT(native);
u.wasm.native_ = native;
u.wasm.jitEntry_ = nullptr;
}
void setWasmJitEntry(void* entry) {
MOZ_ASSERT(isNativeWithJitEntry());
MOZ_ASSERT(entry);
MOZ_ASSERT(!u.wasm.jitEntry_);
u.wasm.jitEntry_ = entry;
}
bool isDerivedClassConstructor();
static unsigned offsetOfNative() {
static_assert(offsetof(U, native.func_) == offsetof(U, wasm.native_),
"native.func_ must be at the same offset as wasm.native_");
return offsetof(JSFunction, u.native.func_);
}
static unsigned offsetOfScript() {
static_assert(offsetof(U, scripted.s.script_) == offsetof(U, wasm.jitEntry_),
"scripted.s.script_ must be at the same offset as wasm.jitEntry_");
return offsetof(JSFunction, u.scripted.s.script_);
}
static unsigned offsetOfNativeOrEnv() {
@ -703,11 +737,12 @@ NewFunctionWithProto(JSContext* cx, JSNative native, unsigned nargs,
inline JSFunction*
NewNativeFunction(JSContext* cx, JSNative native, unsigned nargs, HandleAtom atom,
gc::AllocKind allocKind = gc::AllocKind::FUNCTION,
NewObjectKind newKind = SingletonObject)
NewObjectKind newKind = SingletonObject,
JSFunction::Flags flags = JSFunction::NATIVE_FUN)
{
MOZ_ASSERT(native);
return NewFunctionWithProto(cx, native, nargs, JSFunction::NATIVE_FUN,
nullptr, atom, nullptr, allocKind, newKind);
return NewFunctionWithProto(cx, native, nargs, flags, nullptr, atom, nullptr, allocKind,
newKind);
}
// Allocate a new constructor backed by a JSNative. Note that by default this
@ -720,8 +755,8 @@ NewNativeConstructor(JSContext* cx, JSNative native, unsigned nargs, HandleAtom
{
MOZ_ASSERT(native);
MOZ_ASSERT(flags & JSFunction::NATIVE_CTOR);
return NewFunctionWithProto(cx, native, nargs, flags, nullptr, atom,
nullptr, allocKind, newKind);
return NewFunctionWithProto(cx, native, nargs, flags, nullptr, atom, nullptr, allocKind,
newKind);
}
// Allocate a new scripted function. If enclosingEnv is null, the

View File

@ -1377,8 +1377,8 @@ InitializePropertiesFromCompatibleNativeObject(JSContext* cx,
}
Reverse(shapes.begin(), shapes.end());
for (Shape* shape : shapes) {
Rooted<StackShape> child(cx, StackShape(shape));
for (Shape* shapeToClone : shapes) {
Rooted<StackShape> child(cx, StackShape(shapeToClone));
shape = cx->zone()->propertyTree().getChild(cx, shape, child);
if (!shape)
return false;

View File

@ -465,9 +465,9 @@ js::InternalCallOrConstruct(JSContext* cx, const CallArgs& args, MaybeConstruct
if (fun->isNative()) {
MOZ_ASSERT_IF(construct, !fun->isConstructor());
JSNative native = fun->native();
if (!construct && args.ignoresReturnValue()) {
if (!construct && args.ignoresReturnValue() && fun->hasJitInfo()) {
const JSJitInfo* jitInfo = fun->jitInfo();
if (jitInfo && jitInfo->type() == JSJitInfo::IgnoresReturnValueNative)
if (jitInfo->type() == JSJitInfo::IgnoresReturnValueNative)
native = jitInfo->ignoresReturnValueMethod;
}
return CallJSNative(cx, native, args);
@ -511,7 +511,7 @@ InternalCall(JSContext* cx, const AnyInvokeArgs& args)
HandleValue fval = args.calleev();
if (!fval.isObject() || !fval.toObject().is<JSFunction>() ||
!fval.toObject().as<JSFunction>().isNative() ||
!fval.toObject().as<JSFunction>().jitInfo() ||
!fval.toObject().as<JSFunction>().hasJitInfo() ||
fval.toObject().as<JSFunction>().jitInfo()->needsOuterizedThisObject())
{
JSObject* thisObj = &args.thisv().toObject();

View File

@ -964,7 +964,7 @@ wasm::MaybeGetBuiltinThunk(HandleFunction f, const Sig& sig, JSContext* cx)
{
MOZ_ASSERT(builtinThunks);
if (!f->isNative() || !f->jitInfo() || f->jitInfo()->type() != JSJitInfo::InlinableNative)
if (!f->isNative() || !f->hasJitInfo() || f->jitInfo()->type() != JSJitInfo::InlinableNative)
return nullptr;
Maybe<ABIFunctionType> abiType = ToBuiltinABIFunctionType(sig);

View File

@ -606,6 +606,8 @@ struct nsGridContainerFrame::GridItemInfo
// Return true if we should apply Automatic Minimum Size to this item.
// https://drafts.csswg.org/css-grid/#min-size-auto
// @note the caller should also check that the item spans at least one track
// that has a min track sizing function that is 'auto' before applying it.
bool ShouldApplyAutoMinSize(WritingMode aContainerWM,
LogicalAxis aContainerAxis,
nscoord aPercentageBasis) const
@ -665,6 +667,12 @@ nsGridContainerFrame::GridItemInfo::Dump() const
if (state & ItemState::eIsFlexing) {
printf("flexing ");
}
if (state & ItemState::eApplyAutoMinSize) {
printf("auto-min-size ");
}
if (state & ItemState::eClampMarginBoxMinSize) {
printf("clamp ");
}
if (state & ItemState::eFirstBaseline) {
printf("first baseline %s-alignment ",
(state & ItemState::eSelfBaseline) ? "self" : "content");
@ -1092,15 +1100,9 @@ struct nsGridContainerFrame::Tracks
nscoord aContentBoxSize);
/**
* Return true if aRange spans at least one track with an intrinsic sizing
* function and does not span any tracks with a <flex> max-sizing function.
* @param aRange the span of tracks to check
* @param aState will be set to the union of the state bits of all the spanned
* tracks, unless a flex track is found - then it only contains
* the union of the tracks up to and including the flex track.
* Return the union of the state bits for the tracks in aRange.
*/
bool HasIntrinsicButNoFlexSizingInRange(const LineRange& aRange,
TrackSize::StateBits* aState) const;
TrackSize::StateBits StateBitsForRange(const LineRange& aRange) const;
// Some data we collect for aligning baseline-aligned items.
struct ItemBaselineData
@ -3755,28 +3757,17 @@ nsGridContainerFrame::Tracks::CalculateSizes(
}
}
bool
nsGridContainerFrame::Tracks::HasIntrinsicButNoFlexSizingInRange(
const LineRange& aRange,
TrackSize::StateBits* aState) const
TrackSize::StateBits
nsGridContainerFrame::Tracks::StateBitsForRange(const LineRange& aRange) const
{
MOZ_ASSERT(!aRange.IsAuto(), "must have a definite range");
TrackSize::StateBits state = TrackSize::StateBits(0);
const uint32_t start = aRange.mStart;
const uint32_t end = aRange.mEnd;
const TrackSize::StateBits selector =
TrackSize::eIntrinsicMinSizing | TrackSize::eIntrinsicMaxSizing;
bool foundIntrinsic = false;
for (uint32_t i = start; i < end; ++i) {
TrackSize::StateBits state = mSizes[i].mState;
*aState |= state;
if (state & TrackSize::eFlexMaxSizing) {
return false;
}
if (state & selector) {
foundIntrinsic = true;
}
state |= mSizes[i].mState;
}
return foundIntrinsic;
return state;
}
bool
@ -3791,6 +3782,13 @@ nsGridContainerFrame::Tracks::ResolveIntrinsicSizeStep1(
CachedIntrinsicSizes cache;
TrackSize& sz = mSizes[aRange.mStart];
WritingMode wm = aState.mWM;
// Check if we need to apply "Automatic Minimum Size" and cache it.
if ((sz.mState & TrackSize::eAutoMinSizing) &&
aGridItem.ShouldApplyAutoMinSize(wm, mAxis, aPercentageBasis)) {
aGridItem.mState[mAxis] |= ItemState::eApplyAutoMinSize;
}
// Calculate data for "Automatic Minimum Size" clamping, if needed.
bool needed = ((sz.mState & TrackSize::eIntrinsicMinSizing) ||
aConstraint == SizingConstraint::eNoConstraint) &&
@ -4197,14 +4195,10 @@ nsGridContainerFrame::Tracks::ResolveIntrinsicSize(
iter.Reset();
for (; !iter.AtEnd(); iter.Next()) {
auto& gridItem = aGridItems[iter.ItemIndex()];
// Check if we need to apply "Automatic Minimum Size" and cache it.
MOZ_ASSERT(!(gridItem.mState[mAxis] & ItemState::eApplyAutoMinSize),
"Why is eApplyAutoMinSize set already?");
if (gridItem.ShouldApplyAutoMinSize(wm, mAxis, aPercentageBasis)) {
gridItem.mState[mAxis] |= ItemState::eApplyAutoMinSize;
}
MOZ_ASSERT(!(gridItem.mState[mAxis] &
(ItemState::eApplyAutoMinSize | ItemState::eIsFlexing |
ItemState::eClampMarginBoxMinSize)),
"Why are any of these bits set already?");
const GridArea& area = gridItem.mArea;
const LineRange& lineRange = area.*aRange;
uint32_t span = lineRange.Extent();
@ -4215,8 +4209,17 @@ nsGridContainerFrame::Tracks::ResolveIntrinsicSize(
gridItem.mState[mAxis] |= ItemState::eIsFlexing;
}
} else {
TrackSize::StateBits state = TrackSize::StateBits(0);
if (HasIntrinsicButNoFlexSizingInRange(lineRange, &state)) {
TrackSize::StateBits state = StateBitsForRange(lineRange);
// Check if we need to apply "Automatic Minimum Size" and cache it.
if ((state & TrackSize::eAutoMinSizing) &&
gridItem.ShouldApplyAutoMinSize(wm, mAxis, aPercentageBasis)) {
gridItem.mState[mAxis] |= ItemState::eApplyAutoMinSize;
}
if ((state & (TrackSize::eIntrinsicMinSizing |
TrackSize::eIntrinsicMaxSizing)) &&
!(state & TrackSize::eFlexMaxSizing)) {
// Collect data for Step 2.
maxSpan = std::max(maxSpan, span);
if (span >= stateBitsPerSpan.Length()) {

View File

@ -31,7 +31,7 @@ span {
<div class="grid">
<span>a</span>
<span style="width:28px">IAmReallyWideAndTheBorderShouldSurroundMe</span>
<span style="width:-moz-max-content">IAmReallyWideAndTheBorderShouldSurroundMe</span>
</div>
<pre>The border shouldn't shrink-wrap the wide text below, due to definite "width" values:</pre>
@ -48,18 +48,18 @@ span {
<div class="grid" style="margin-bottom:50px;">
<span>a</span>
<span style="font-size:72px;width:28px;height:28px">IAmReallyTall</span>
<span style="font-size:72px;width:-moz-max-content;height:-moz-max-content">IAmReallyTall</span>
<span>c</span>
<span>d</span>
</div>
The border shouldn't shrink-wrap the wide text below, due to definite "height" values:
The border shouldn't shrink-wrap the text vertically below, due to definite "height" values:
<div class="grid">
<span>a</span>
<span style="font-size:72px; height:10%;width:28px">IAmReallyTall</span>
<span style="font-size:72px; height:10%;width:-moz-max-content">IAmReallyTall</span>
<span>c</span>
<span style="font-size:72px; height:10px;width:28px">SameHere</span>
<span style="font-size:72px; height:40px;width:28px">SameHere</span>
<span style="font-size:72px; height:10px;width:-moz-max-content">SameHere</span>
<span style="font-size:72px; height:40px;width:-moz-max-content">SameHere</span>
</div>
</body>

View File

@ -53,7 +53,7 @@ span {
<span>d</span>
</div>
The border shouldn't shrink-wrap the wide text below, due to definite "height" values:
The border shouldn't shrink-wrap the text vertically below, due to definite "height" values:
<div class="grid">
<span>a</span>
<span style="font-size:72px; height:10%">IAmReallyTall</span>

View File

@ -40,7 +40,7 @@ pre {
<div class="grid" style="margin-left:0">
<span>a</span>
<span style="height:28px">IAmReallyWideAndTheBorderShouldSurroundMe</span>
<span style="height:-moz-max-content">IAmReallyWideAndTheBorderShouldSurroundMe</span>
</div>
<pre>The border shouldn't shrink-wrap the wide text below, due to definite "height" values:</pre>
@ -57,7 +57,7 @@ pre {
<div class="grid" style="margin-bottom:50px;">
<span>a</span>
<span style="font-size:72px;height:28px;width:28px">IAmReallyTall</span>
<span style="font-size:72px;height:-moz-max-content;width:-moz-max-content">IAmReallyTall</span>
<span>c</span>
<span>d</span>
</div>
@ -65,10 +65,10 @@ pre {
<pre>The border shouldn't shrink-wrap the wide text below, due to definite "width" values:</pre>
<div class="grid">
<span>a</span>
<span style="font-size:72px; width:10%;height:28px">IAmReallyTall</span>
<span style="font-size:72px; width:10%;height:-moz-max-content">IAmReallyTall</span>
<span>c</span>
<span style="font-size:72px; width:10px;height:28px">SameHere</span>
<span style="font-size:72px; width:40px;height:28px">SameHere</span>
<span style="font-size:72px; width:10px;height:-moz-max-content">SameHere</span>
<span style="font-size:72px; width:40px;height:-moz-max-content">SameHere</span>
</div>
</body>

View File

@ -32,13 +32,13 @@ body,html { color:black; background:white; font:16px/1 monospace; padding:0; mar
grid-template-rows: repeat(2,10px);
}
.min {
grid-template-columns: repeat(2,minmax(min-content, 15px));
grid-template-rows: repeat(2,minmax(min-content, 10px));
}
.max {
grid-template-columns: repeat(2,minmax(max-content, 15px));
grid-template-rows: repeat(2,minmax(max-content, 10px));
}
.max {
grid-template-columns: repeat(2,minmax(min-content, 15px));
grid-template-rows: repeat(2,minmax(min-content, 10px));
}
.larger .grid {
grid-template-columns: repeat(2,minmax(auto, 25px));
@ -92,21 +92,13 @@ span {
border: 1px solid;
padding: 1px 3px 5px 7px;
margin: 3px 5px 7px 1px;
width: 0;
height: 0;
}
.span2 {
grid-area: 1 / 1 / span 2 / span 2;
width: 13px;
height: 3px;
}
.grid.max span {
width:20px;
}
.larger .grid span {
width: 7px;
height: 10px;
}
.larger .grid .span2 {
font-size: 32px;
width: 20px;

View File

@ -32,13 +32,13 @@ body,html { color:black; background:white; font:16px/1 monospace; padding:0; mar
grid-template-rows: repeat(2,10px);
}
.min {
grid-template-columns: repeat(2,minmax(min-content, 15px));
grid-template-rows: repeat(2,minmax(min-content, 10px));
}
.max {
grid-template-columns: repeat(2,minmax(max-content, 15px));
grid-template-rows: repeat(2,minmax(max-content, 10px));
}
.max {
grid-template-columns: repeat(2,minmax(min-content, 15px));
grid-template-rows: repeat(2,minmax(min-content, 10px));
}
.larger .grid {
grid-template-columns: repeat(2,minmax(auto, 25px));
@ -49,13 +49,13 @@ body,html { color:black; background:white; font:16px/1 monospace; padding:0; mar
grid-template-rows: repeat(2,28px);
}
.larger .min {
grid-template-columns: repeat(2,minmax(min-content, 25px));
grid-template-rows: repeat(2,minmax(min-content, 28px));
}
.larger .max {
grid-template-columns: repeat(2,minmax(max-content, 25px));
grid-template-rows: repeat(2,minmax(max-content, 28px));
}
.larger .max {
grid-template-columns: repeat(2,minmax(min-content, 25px));
grid-template-rows: repeat(2,minmax(min-content, 28px));
}
.stretch .grid {
align-items: stretch;
@ -77,17 +77,9 @@ span {
border: 1px solid;
padding: 1px 3px 5px 7px;
margin: 3px 5px 7px 1px;
width: 0;
height: 0;
}
.span2 {
grid-area: 1 / 1 / span 2 / span 2;
width: 13px;
height: 3px;
}
.larger .grid span {
width: 7px;
height: 10px;
}
.larger .grid .span2 {
font-size: 32px;

View File

@ -78,8 +78,8 @@ img {
border: 1px solid;
padding: 1px 3px 5px 7px;
margin: 3px 5px 7px 1px;
width: 0;
height: 0;
min-width: 0;
min-height: 0;
}
.span2 {
grid-area: 1 / 1 / span 2 / span 2;
@ -156,37 +156,37 @@ document.body.appendChild(wrap);
var imgSizes =
[
['0px', '0px'],
['20px', '32px'],
['2px', '3px'],
['20px', '32px'],
['0px', '0px'],
['2px', '3px'],
['2px', '3px'],
['0px', '0px'],
['0px', '0px'],
['2px', '3px'],
['2px', '3px'],
['0px', '0px'],
['2px', '3px'],
['0px', '0px'],
['20px', '32px'],
['2px', '3px'],
['20px', '32px'],
['20px', '32px'],
['20px', '32px'],
['20px', '32px'],
['6px', '10px'],
['6px', '10px'],
['20px', '32px'],
['20px', '32px'],
['6px', '10px'],
['6px', '10px'],
['20px', '32px'],
['20px', '32px'],
['20px', '32px'],
['6px', '10px'],
['20px', '32px'],
['20px', '32px'],
['20px', '32px'],
['6px', '10px'],
['20px', '32px'],
['20px', '32px'],
['20px', '32px'],
['20px', '32px'],
['20px', '32px'],
['20px', '32px'],
['20px', '32px'],
['20px', '32px'],
['20px', '32px'],
['20px', '32px'],
['20px', '32px'],
['0px', '0px'],
['0px', '0px'],
['13px', '3px'],
@ -195,10 +195,10 @@ var imgSizes =
['0px', '0px'],
['13px', '3px'],
['13px', '3px'],
['0px', '0px'],
['13px', '3px'],
['0px', '0px'],
['13px', '3px'],
['20px', '32px'],
['20px', '32px'],
['20px', '32px'],
['20px', '32px'],
['20px', '32px'],
['20px', '32px'],
['20px', '32px'],
@ -211,9 +211,9 @@ var imgSizes =
['7px', '10px'],
['22px', '32px'],
['33px', '39px'],
['7px', '10px'],
['20px', '32px'],
['33px', '39px'],
['7px', '10px'],
['20px', '32px'],
['22px', '32px'],
['20px', '32px'],
['33px', '39px'],

View File

@ -34,13 +34,13 @@ body,html { color:black; background:white; font:16px/1 monospace; padding:0; mar
grid-template-rows: repeat(2,10px);
}
.min {
grid-template-columns: repeat(2,minmax(min-content, 15px));
grid-template-rows: repeat(2,minmax(min-content, 10px));
}
.max {
grid-template-columns: repeat(2,minmax(max-content, 15px));
grid-template-rows: repeat(2,minmax(max-content, 10px));
}
.max {
grid-template-columns: repeat(2,minmax(min-content, 15px));
grid-template-rows: repeat(2,minmax(min-content, 10px));
}
.larger .grid {
grid-template-columns: repeat(2,minmax(auto, 25px));
@ -51,13 +51,13 @@ body,html { color:black; background:white; font:16px/1 monospace; padding:0; mar
grid-template-rows: repeat(2,28px);
}
.larger .min {
grid-template-columns: repeat(2,minmax(min-content, 25px));
grid-template-rows: repeat(2,minmax(min-content, 28px));
}
.larger .max {
grid-template-columns: repeat(2,minmax(max-content, 25px));
grid-template-rows: repeat(2,minmax(max-content, 28px));
}
.larger .max {
grid-template-columns: repeat(2,minmax(min-content, 25px));
grid-template-rows: repeat(2,minmax(min-content, 28px));
}
.stretch .grid {
align-items: stretch;

View File

@ -74,31 +74,12 @@ span {
.span2 {
grid-area: 1 / 1 / span 2 / span 2;
}
.larger .grid .span2 {
font-size: 32px;
}
.larger .grid span {
align-self:center;
justify-self:center;
}
.larger .grid .span2 {
font-size: 32px;
font-size: 16px;
width: 20px;
height: 32px;
}
.stretch.larger .grid .span2 {
align-self:center;
justify-self:center;
}
.stretch.larger .grid.sz .span2 {
align-self:center;
justify-self:center;
}
.stretch.larger .grid.definite .span2 {
align-self:center;
justify-self:center;
}
x {
grid-area: 1 / 1;
@ -117,6 +98,14 @@ c {
br {
clear: both;
}
.larger .center > span {
justify-self: center;
align-self: center;
}
.larger .ml4 > span {
margin-left: 4px;
}
</style>
</head>
<body>
@ -124,25 +113,25 @@ br {
<div id="tests">
<div class="grid"><x></x><span><c>X</c></span></div>
<div class="grid definite"><x></x><span><c>X</c></span></div>
<div class="grid"><x></x><span class="span2"><c>X</c></span></div>
<div class="grid definite"><x></x><span class="span2"><c>X</c></span></div>
<div class="grid center"><x></x><span class="span2"><c>X</c></span></div>
<div class="grid center definite"><x></x><span class="span2"><c>X</c></span></div>
<div class="grid sz"><x></x><span><c>X</c></span></div>
<div class="grid sz definite"><x></x><span><c>X</c></span></div>
<div class="grid sz"><x></x><span class="span2"><c>X</c></span></div>
<div class="grid sz definite"><x></x><span class="span2"><c>X</c></span></div>
<div class="grid ml4 sz"><x></x><span class="span2"><c>X</c></span></div>
<div class="grid center sz definite"><x></x><span class="span2"><c>X</c></span></div>
<br>
<div class="grid min"><x></x><span><c>X</c></span></div>
<div class="grid min"><x></x><span class="span2"><c>X</c></span></div>
<div class="grid center min"><x></x><span class="span2"><c>X</c></span></div>
<div class="grid sz min"><x></x><span><c>X</c></span></div>
<div class="grid sz min"><x></x><span class="span2"><c>X</c></span></div>
<div class="grid ml4 sz min"><x></x><span class="span2"><c>X</c></span></div>
<div class="grid max"><x></x><span><c>X</c></span></div>
<div class="grid max"><x></x><span class="span2"><c>X</c></span></div>
<div class="grid center max"><x></x><span class="span2"><c>X</c></span></div>
<div class="grid sz max"><x></x><span><c>X</c></span></div>
<div class="grid sz max"><x></x><span class="span2"><c>X</c></span></div>
<div class="grid ml4 sz max"><x></x><span class="span2"><c>X</c></span></div>
<br>
@ -157,6 +146,7 @@ wrap.className = 'larger';
wrap.appendChild(n);
document.body.appendChild(wrap);
/* TODO: sort out https://bugs.chromium.org/p/chromium/issues/detail?id=789927 first
var n = tests.cloneNode(true);
var wrap = document.createElement('div');
wrap.className = 'stretch';
@ -168,6 +158,7 @@ var wrap = document.createElement('div');
wrap.className = 'stretch larger';
wrap.appendChild(n);
document.body.appendChild(wrap);
*/
</script>

View File

@ -77,7 +77,7 @@ span {
grid-area: 1 / 1 / span 2 / span 2;
}
.larger .grid .span2 {
font-size: 32px;
font-size: 16px;
}
x {
@ -137,6 +137,7 @@ wrap.className = 'larger';
wrap.appendChild(n);
document.body.appendChild(wrap);
/* TODO: sort out https://bugs.chromium.org/p/chromium/issues/detail?id=789927 first
var n = tests.cloneNode(true);
var wrap = document.createElement('div');
wrap.className = 'stretch';
@ -148,6 +149,7 @@ var wrap = document.createElement('div');
wrap.className = 'stretch larger';
wrap.appendChild(n);
document.body.appendChild(wrap);
*/
</script>

View File

@ -23,13 +23,11 @@ body,html { color:black; background:white; font:16px/1 monospace; padding:0; mar
margin-bottom: 14px;
}
.c-auto { grid-template-columns: 15px; width: 15px; }
.c-min { grid-template-columns: 15px; width: 15px; }
.c-max { grid-template-columns: 15px; width: 15px; }
.c-1530 { grid-template-columns: 15px; width: 30px; }
.c-30 { grid-template-columns: 30px; width: 30px; }
.r-auto { grid-template-rows: 15px; height: 15px; }
.r-min { grid-template-rows: 15px; height: 15px; }
.r-max { grid-template-rows: 15px; height: 15px; }
.r-min { grid-template-rows: 40px; height: 40px; }
.r-max { grid-template-rows: 40px; height: 40px; }
span {
grid-area: 1 / 1;
font-size: 48px;
@ -55,6 +53,7 @@ span { width:15px; }
.r span { width:20px; }
.grid.c-30 span, .r.grid.c-30 span { width:30px; }
.r span { height:15px; }
.r.r-min span, .r.r-max span { height:40px; }
</style>
</head>
<body>
@ -67,16 +66,16 @@ span { width:15px; }
<br>
<div class="grid c-min"><y></y><span><x>X</x></span></div>
<div class="grid c-min"><y></y><span><x>X</x></span></div>
<div class="grid c-30" style="width:30px"><y style="width:30px"></y><span><x>X</x></span></div>
<div class="grid c-min"><y></y><span><x>X</x></span></div>
<div class="grid c-min"><y></y><span><x>X</x></span></div>
<div class="grid c-30"><y></y><span><x>X</x></span></div>
<div class="grid c-30"><y></y><span><x>X</x></span></div>
<div class="grid c-30"><y></y><span><x>X</x></span></div>
<div class="grid c-30"><y></y><span><x>X</x></span></div>
<div class="grid c-30"><y></y><span><x>X</x></span></div>
<br>
<div class="grid c-30"><y></y><span><x>X</x></span></div>
<div class="grid c-max"><y></y><span><x>X</x></span></div>
<div class="grid c-30"><y></y><span><x>X</x></span></div>
<div class="grid c-30"><y></y><span><x>X</x></span></div>
<div class="grid c-30"><y></y><span><x>X</x></span></div>
<div class="grid c-30"><y></y><span><x>X</x></span></div>
@ -107,32 +106,8 @@ span { width:15px; }
<br>
<div class="grid r c-min r-auto"><y></y><span><x>X</x></span></div>
<div class="grid r c-min r-auto"><y></y><span><x>X</x></span></div>
<div class="grid r c-30 r-auto"><y></y><span><x>X</x></span></div>
<div class="grid r c-min r-auto"><y></y><span><x>X</x></span></div>
<div class="grid r c-min r-auto"><y></y><span><x>X</x></span></div>
<br>
<div class="grid r c-min r-min"><y></y><span><x>X</x></span></div>
<div class="grid r c-min r-min"><y></y><span><x>X</x></span></div>
<div class="grid r c-30 r-min"><y></y><span><x>X</x></span></div>
<div class="grid r c-min r-min"><y></y><span><x>X</x></span></div>
<div class="grid r c-min r-min"><y></y><span><x>X</x></span></div>
<br>
<div class="grid r c-min r-max"><y></y><span><x>X</x></span></div>
<div class="grid r c-min r-max"><y></y><span><x>X</x></span></div>
<div class="grid r c-30 r-max"><y></y><span><x>X</x></span></div>
<div class="grid r c-min r-max"><y></y><span><x>X</x></span></div>
<div class="grid r c-min r-max"><y></y><span><x>X</x></span></div>
<br>
<div class="grid r c-30 r-auto"><y></y><span><x>X</x></span></div>
<div class="grid r c-max r-auto"><y></y><span><x>X</x></span></div>
<div class="grid r c-30 r-auto"><y></y><span><x>X</x></span></div>
<div class="grid r c-30 r-auto"><y></y><span><x>X</x></span></div>
<div class="grid r c-30 r-auto"><y></y><span><x>X</x></span></div>
<div class="grid r c-30 r-auto"><y></y><span><x>X</x></span></div>
@ -140,7 +115,7 @@ span { width:15px; }
<br>
<div class="grid r c-30 r-min"><y></y><span><x>X</x></span></div>
<div class="grid r c-max r-min"><y></y><span><x>X</x></span></div>
<div class="grid r c-30 r-min"><y></y><span><x>X</x></span></div>
<div class="grid r c-30 r-min"><y></y><span><x>X</x></span></div>
<div class="grid r c-30 r-min"><y></y><span><x>X</x></span></div>
<div class="grid r c-30 r-min"><y></y><span><x>X</x></span></div>
@ -148,7 +123,31 @@ span { width:15px; }
<br>
<div class="grid r c-30 r-max"><y></y><span><x>X</x></span></div>
<div class="grid r c-max r-max"><y></y><span><x>X</x></span></div>
<div class="grid r c-30 r-max"><y></y><span><x>X</x></span></div>
<div class="grid r c-30 r-max"><y></y><span><x>X</x></span></div>
<div class="grid r c-30 r-max"><y></y><span><x>X</x></span></div>
<div class="grid r c-30 r-max"><y></y><span><x>X</x></span></div>
<br>
<div class="grid r c-30 r-auto"><y></y><span><x>X</x></span></div>
<div class="grid r c-30 r-auto"><y></y><span><x>X</x></span></div>
<div class="grid r c-30 r-auto"><y></y><span><x>X</x></span></div>
<div class="grid r c-30 r-auto"><y></y><span><x>X</x></span></div>
<div class="grid r c-30 r-auto"><y></y><span><x>X</x></span></div>
<br>
<div class="grid r c-30 r-min"><y></y><span><x>X</x></span></div>
<div class="grid r c-30 r-min"><y></y><span><x>X</x></span></div>
<div class="grid r c-30 r-min"><y></y><span><x>X</x></span></div>
<div class="grid r c-30 r-min"><y></y><span><x>X</x></span></div>
<div class="grid r c-30 r-min"><y></y><span><x>X</x></span></div>
<br>
<div class="grid r c-30 r-max"><y></y><span><x>X</x></span></div>
<div class="grid r c-30 r-max"><y></y><span><x>X</x></span></div>
<div class="grid r c-30 r-max"><y></y><span><x>X</x></span></div>
<div class="grid r c-30 r-max"><y></y><span><x>X</x></span></div>
<div class="grid r c-30 r-max"><y></y><span><x>X</x></span></div>

View File

@ -9,7 +9,17 @@
<link rel="author" title="Mats Palmgren" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1314206">
<style type="text/css">
body,html { color:black; background:white; font:16px/1 monospace; padding:0; margin:0; }
* { font:16px/1 monospace; }
.grid2 {
display: grid;
float: left;
grid: auto-flow auto / 10px 30px 10px 30px 10px 30px 10px 30px auto auto auto auto;
grid-gap: 5px;
margin-bottom:20px;
margin-right:20px;
border:1px solid;
}
.grid {
display: block;
float: left;
@ -22,7 +32,9 @@ button {
border: 1px solid;
padding: 0;
margin: 0;
vertical-align:top;
vertical-align: top;
box-sizing: border-box;
min-width: 0;
}
button:nth-child(1n) { background: blue; }
button:nth-child(2n) { background: grey; }
@ -44,8 +56,13 @@ a30 {
display: inline-block;
height: 0;
width: 30px;
margin-left: 5px;
text-align: right;
direction: rtl;
}
a10 {
display: inline-block;
height: 0;
width: 10px;
direction: rtl;
}
.rel > button {
position:absolute;
@ -55,35 +72,35 @@ a30 {
<body>
<div class="grid sz">
<button>AB</button><button style="margin-left:-5px">AB</button><button style="margin-left:5px">AB</button><button style="margin-left:15px">AB</button><button style="margin-left:5px">AB</button><button style="margin-left:-5px">AB</button><button style="margin-left:5px">AB</button><button style="margin-left:15px">AB</button><button style="margin-left:5px">AB</button><button style="margin-left:5px">AB</button><button style="margin-left:5px">AB</button><button style="margin-left:5px">AB</button></div>
<button>&nbsp;&nbsp;</button><button style="margin-left:-5px">&nbsp;&nbsp;</button><button style="margin-left:5px">&nbsp;&nbsp;</button><button style="margin-left:15px">&nbsp;&nbsp;</button><button style="margin-left:5px">&nbsp;&nbsp;</button><button style="margin-left:-5px">&nbsp;&nbsp;</button><button style="margin-left:5px">&nbsp;&nbsp;</button><button style="margin-left:15px">&nbsp;&nbsp;</button><button style="margin-left:5px">&nbsp;&nbsp;</button><button style="margin-left:5px">&nbsp;&nbsp;</button><button style="margin-left:5px">&nbsp;&nbsp;</button><button style="margin-left:5px">&nbsp;&nbsp;</button></div>
<div class="grid sz t2">
<button>AB</button><button style="margin-left:5px">AB</button><button style="margin-left:25px">AB</button><button style="margin-left:25px">AB</button><button style="margin-left:5px">AB</button><button style="margin-left:5px">AB</button><button style="margin-left:25px">AB</button><button style="margin-left:25px">AB</button><button style="margin-left:5px">AB</button><button style="margin-left:5px">AB</button><button style="margin-left:5px">AB</button><button style="margin-left:5px">AB</button></div>
<button>&nbsp;&nbsp;</button><button style="margin-left:5px">&nbsp;&nbsp;</button><button style="margin-left:25px">&nbsp;&nbsp;</button><button style="margin-left:25px">&nbsp;&nbsp;</button><button style="margin-left:5px">&nbsp;&nbsp;</button><button style="margin-left:5px">&nbsp;&nbsp;</button><button style="margin-left:25px">&nbsp;&nbsp;</button><button style="margin-left:25px">&nbsp;&nbsp;</button><button style="margin-left:5px">&nbsp;&nbsp;</button><button style="margin-left:5px">&nbsp;&nbsp;</button><button style="margin-left:5px">&nbsp;&nbsp;</button><button style="margin-left:5px">&nbsp;&nbsp;</button></div>
<div class="grid" style="width:215px">
<button style="width:10px">AB</button><button style="width:30px;margin-left:5px">AB</button><button style="width:10px;margin-left:5px">AB</button><a30><button style="background:silver">AB</button></a30><button style="width:10px;margin-left:5px">AB</button><button style="width:30px;margin-left:5px">AB</button><button style="width:10px;margin-left:5px">AB</button><a30><button style="background:silver;">AB</button></a30></div>
<div class="grid2" style="width:215px">
<button style="width:10px">&nbsp;&nbsp;</button><button style="width:30px">&nbsp;&nbsp;</button><a10><button style="background:tan">&nbsp;&nbsp;</button></a10><a30><button style="background:silver">&nbsp;&nbsp;</button></a30><button style="width:10px">&nbsp;&nbsp;</button><button style="width:30px">&nbsp;&nbsp;</button><a10><button>&nbsp;&nbsp;</button></a10><a30><button style="background:silver;">&nbsp;&nbsp;</button></a30></div>
<div class="grid">
<button>AB</button><button>AB</button><br><button style="background:tan">AB</button><button style="background:silver">AB</button></div>
<button>&nbsp;&nbsp;</button><button>&nbsp;&nbsp;</button><br><button style="background:tan">&nbsp;&nbsp;</button><button style="background:silver">&nbsp;&nbsp;</button></div>
<div class="grid rel" style="width:100px; height:100px; position:relative">
<button style="top:0;width:50px;height:50px">AB</button><button style="top:0;right:0;height:50px">&nbsp;&nbsp;</button><button style="bottom:0;width:50px;">AB</button><button style="bottom:0;right:0">&nbsp;&nbsp;</button></div>
<button style="top:0;width:50px;height:50px">&nbsp;&nbsp;</button><button style="top:0;right:0;height:50px">&nbsp;&nbsp;</button><button style="bottom:0;width:50px;">&nbsp;&nbsp;</button><button style="bottom:0;right:0">&nbsp;&nbsp;</button></div>
<div class="grid rel" style="height:40px; position:relative">
<button style="left:0;top:0;height:20px">AB</button><button style="top:0;right:0;height:20px">AB</button><button style="left:0;bottom:0;">AB</button><button style="bottom:0;right:0">AB</button><button style="position:static;visibility:hidden">AB</button><button style="position:static;visibility:hidden">AB</button>
<button style="left:0;top:0;height:20px">&nbsp;&nbsp;</button><button style="top:0;right:0;height:20px">&nbsp;&nbsp;</button><button style="left:0;bottom:0;">&nbsp;&nbsp;</button><button style="bottom:0;right:0">&nbsp;&nbsp;</button><button style="position:static;visibility:hidden">&nbsp;&nbsp;</button><button style="position:static;visibility:hidden">&nbsp;&nbsp;</button>
</div>
<div class="grid sz t2 mw">
<button>AB</button><button>AB</button><button style="margin-left:15px">AB</button><button style="margin-left:20px">AB</button><button style="margin-left:5px">AB</button><button>AB</button><button style="margin-left:15px">AB</button><button style="margin-left:20px">AB</button><button style="margin-left:5px">AB</button><button style="margin-left:5px">AB</button><button style="margin-left:5px">AB</button><button style="margin-left:5px">AB</button></div>
<button>&nbsp;&nbsp;</button><button>&nbsp;&nbsp;</button><button style="margin-left:15px">&nbsp;&nbsp;</button><button style="margin-left:20px">&nbsp;&nbsp;</button><button style="margin-left:5px">&nbsp;&nbsp;</button><button>&nbsp;&nbsp;</button><button style="margin-left:15px">&nbsp;&nbsp;</button><button style="margin-left:20px">&nbsp;&nbsp;</button><button style="margin-left:5px">&nbsp;&nbsp;</button><button style="margin-left:5px">&nbsp;&nbsp;</button><button style="margin-left:5px">&nbsp;&nbsp;</button><button style="margin-left:5px">&nbsp;&nbsp;</button></div>
<div class="grid mw40" style="width:215px">
<button>AB</button><button style="margin-left:-25px">AB</button><button style="margin-left:-35px">AB</button><button style="margin-left:-5px">AB</button><button style="margin-left:5px">AB</button><button style="margin-left:-25px">AB</button><button style="margin-left:-35px">AB</button><button style="margin-left:-5px">AB</button></div>
<button>&nbsp;&nbsp;</button><button style="margin-left:-25px">&nbsp;&nbsp;</button><button style="margin-left:-35px">&nbsp;&nbsp;</button><button style="margin-left:-5px">&nbsp;&nbsp;</button><button style="margin-left:5px">&nbsp;&nbsp;</button><button style="margin-left:-25px">&nbsp;&nbsp;</button><button style="margin-left:-35px">&nbsp;&nbsp;</button><button style="margin-left:-5px">&nbsp;&nbsp;</button></div>
<div class="grid rel" style="width:100px; height:100px; position:relative">
<button style="top:0;width:40px;height:40px">AB</button><button style="top:0;right:0;height:40px">&nbsp;&nbsp;</button><button style="bottom:0;width:40px;">AB</button><button style="bottom:0;right:0">&nbsp;&nbsp;</button></div>
<button style="top:0;width:40px;height:40px">&nbsp;&nbsp;</button><button style="top:0;right:0;height:40px">&nbsp;&nbsp;</button><button style="bottom:0;width:40px;">&nbsp;&nbsp;</button><button style="bottom:0;right:0">&nbsp;&nbsp;</button></div>
<div class="grid rel" style="width:100px; height:100px; position:relative">
<button style="top:0;width:40px;height:40px">AB</button><button style="top:0;right:0;height:40px">&nbsp;&nbsp;</button><button style="bottom:0;width:40px;">AB</button><button style="bottom:0;right:0">&nbsp;&nbsp;</button></div>
<button style="top:0;width:40px;height:40px">&nbsp;&nbsp;</button><button style="top:0;right:0;height:40px">&nbsp;&nbsp;</button><button style="bottom:0;width:40px;">&nbsp;&nbsp;</button><button style="bottom:0;right:0">&nbsp;&nbsp;</button></div>
</body>
</html>

View File

@ -11,6 +11,7 @@
<link rel="match" href="grid-item-button-001-ref.html">
<style type="text/css">
body,html { color:black; background:white; font:16px/1 monospace; padding:0; margin:0; }
* { font:16px/1 monospace; }
.grid {
display: grid;
@ -55,104 +56,104 @@ button:nth-child(4n) { background: silver; }
<body>
<div class="grid sz">
<button>AB</button>
<button>AB</button>
<button class="jend">AB</button>
<button class="jend">AB</button>
<button class="aend">AB</button>
<button class="aend">AB</button>
<button class="end">AB</button>
<button class="end">AB</button>
<button>AB</button>
<button class="jend">AB</button>
<button class="aend">AB</button>
<button class="end">AB</button>
<button>&nbsp;&nbsp;</button>
<button>&nbsp;&nbsp;</button>
<button class="jend">&nbsp;&nbsp;</button>
<button class="jend">&nbsp;&nbsp;</button>
<button class="aend">&nbsp;&nbsp;</button>
<button class="aend">&nbsp;&nbsp;</button>
<button class="end">&nbsp;&nbsp;</button>
<button class="end">&nbsp;&nbsp;</button>
<button>&nbsp;&nbsp;</button>
<button class="jend">&nbsp;&nbsp;</button>
<button class="aend">&nbsp;&nbsp;</button>
<button class="end">&nbsp;&nbsp;</button>
</div>
<div class="grid sz t2">
<button>AB</button>
<button>AB</button>
<button class="jend">AB</button>
<button class="jend">AB</button>
<button class="aend">AB</button>
<button class="aend">AB</button>
<button class="end">AB</button>
<button class="end">AB</button>
<button>AB</button>
<button class="jend">AB</button>
<button class="aend">AB</button>
<button class="end">AB</button>
<button>&nbsp;&nbsp;</button>
<button>&nbsp;&nbsp;</button>
<button class="jend">&nbsp;&nbsp;</button>
<button class="jend">&nbsp;&nbsp;</button>
<button class="aend">&nbsp;&nbsp;</button>
<button class="aend">&nbsp;&nbsp;</button>
<button class="end">&nbsp;&nbsp;</button>
<button class="end">&nbsp;&nbsp;</button>
<button>&nbsp;&nbsp;</button>
<button class="jend">&nbsp;&nbsp;</button>
<button class="aend">&nbsp;&nbsp;</button>
<button class="end">&nbsp;&nbsp;</button>
</div>
<div class="grid">
<button>AB</button>
<button>AB</button>
<button class="jend">AB</button>
<button class="jend">AB</button>
<button class="aend">AB</button>
<button class="aend">AB</button>
<button class="end">AB</button>
<button class="end">AB</button>
<button>&nbsp;&nbsp;</button>
<button>&nbsp;&nbsp;</button>
<button class="jend">&nbsp;&nbsp;</button>
<button class="jend">&nbsp;&nbsp;</button>
<button class="aend">&nbsp;&nbsp;</button>
<button class="aend">&nbsp;&nbsp;</button>
<button class="end">&nbsp;&nbsp;</button>
<button class="end">&nbsp;&nbsp;</button>
</div>
<div class="grid" style="grid: auto/auto auto; grid-gap: 0;">
<button>AB</button>
<button class="jend">AB</button>
<button class="aend">AB</button>
<button class="end">AB</button>
<button>&nbsp;&nbsp;</button>
<button class="jend">&nbsp;&nbsp;</button>
<button class="aend">&nbsp;&nbsp;</button>
<button class="end">&nbsp;&nbsp;</button>
</div>
<div class="grid" style="grid: 50px 50px/50px 50px; grid-gap: 0;">
<button>AB</button>
<button>&nbsp;&nbsp;</button>
<button class="jend">&nbsp;&nbsp;</button>
<button class="aend">AB</button>
<button class="aend">&nbsp;&nbsp;</button>
<button class="end">&nbsp;&nbsp;</button>
</div>
<div class="grid" style="grid: minmax(auto,20px) 20px/auto auto; grid-gap: 0;">
<button>AB</button>
<button class="jend">AB</button>
<button class="aend">AB</button>
<button class="end">AB</button>
<button>&nbsp;&nbsp;</button>
<button class="jend">&nbsp;&nbsp;</button>
<button class="aend">&nbsp;&nbsp;</button>
<button class="end">&nbsp;&nbsp;</button>
</div>
<div class="grid sz t2 mw">
<button>AB</button>
<button>AB</button>
<button class="jend">AB</button>
<button class="jend">AB</button>
<button class="aend">AB</button>
<button class="aend">AB</button>
<button class="end">AB</button>
<button class="end">AB</button>
<button>AB</button>
<button class="jend">AB</button>
<button class="aend">AB</button>
<button class="end">AB</button>
<button>&nbsp;&nbsp;</button>
<button>&nbsp;&nbsp;</button>
<button class="jend">&nbsp;&nbsp;</button>
<button class="jend">&nbsp;&nbsp;</button>
<button class="aend">&nbsp;&nbsp;</button>
<button class="aend">&nbsp;&nbsp;</button>
<button class="end">&nbsp;&nbsp;</button>
<button class="end">&nbsp;&nbsp;</button>
<button>&nbsp;&nbsp;</button>
<button class="jend">&nbsp;&nbsp;</button>
<button class="aend">&nbsp;&nbsp;</button>
<button class="end">&nbsp;&nbsp;</button>
</div>
<div class="grid mw40">
<button>AB</button>
<button>AB</button>
<button class="jend">AB</button>
<button class="jend">AB</button>
<button class="aend">AB</button>
<button class="aend">AB</button>
<button class="end">AB</button>
<button class="end">AB</button>
<button>&nbsp;&nbsp;</button>
<button>&nbsp;&nbsp;</button>
<button class="jend">&nbsp;&nbsp;</button>
<button class="jend">&nbsp;&nbsp;</button>
<button class="aend">&nbsp;&nbsp;</button>
<button class="aend">&nbsp;&nbsp;</button>
<button class="end">&nbsp;&nbsp;</button>
<button class="end">&nbsp;&nbsp;</button>
</div>
<div class="grid max40" style="grid:50px 50px/50px 50px; grid-gap: 0;">
<button>AB</button>
<button>&nbsp;&nbsp;</button>
<button class="jend">&nbsp;&nbsp;</button>
<button class="aend">AB</button>
<button class="aend">&nbsp;&nbsp;</button>
<button class="end">&nbsp;&nbsp;</button>
</div>
<div class="grid max40" style="grid:50px 50px/50px 50px; place-items:stretch; grid-gap: 0;">
<button>AB</button>
<button>&nbsp;&nbsp;</button>
<button class="jend">&nbsp;&nbsp;</button>
<button class="aend">AB</button>
<button class="aend">&nbsp;&nbsp;</button>
<button class="end">&nbsp;&nbsp;</button>
</div>

View File

@ -38,13 +38,20 @@ canvas {
<div class="block sz t2">
<canvas></canvas><canvas style="margin-left:5px"></canvas><canvas style="margin-left:25px"></canvas><canvas style="margin-left:25px"></canvas><canvas style="margin-left:5px"></canvas><canvas style="margin-left:5px"></canvas><canvas style="margin-left:25px"></canvas><canvas style="margin-left:25px"></canvas><canvas style="margin-left:5px"></canvas><canvas style="margin-left:5px"></canvas><canvas style="margin-left:5px"></canvas><canvas style="margin-left:5px"></canvas></div>
<div class="block" style="height:150px; width:215px">
<canvas style="width:10px;height:5px;"></canvas><canvas style="width:30px;height:15px;margin-left:5px"></canvas><canvas style="width:10px;height:5px;margin-left:5px"></canvas><canvas style="width:30px;height:15px;margin-left:5px"></canvas><canvas style="width:10px;height:5px;vertical-align:bottom;margin-top:145px;margin-left:5px"></canvas><canvas style="width:30px;height:15px;vertical-align:bottom;margin-top:135px;margin-left:5px"></canvas><canvas style="width:10px;height:5px;vertical-align:bottom;margin-top:145px;margin-left:5px"></canvas><canvas style="width:30px;height:15px;vertical-align:bottom;margin-top:135px;margin-left:5px"></canvas></div>
<br clear=all>
<br clear=all>
<div class="block" style="height:150px; width:215px; white-space:pre">
<canvas style="width:195px; height:150px; background:black"></canvas><canvas style="width:220px; height:150px; background:tan"></canvas></div>
<div class="block" style="height:300px; width:600px"><canvas style="width:300px;height:150px"></canvas><canvas style="width:300px;height:150px"></canvas><canvas style="width:300px;height:150px"></canvas><canvas style="width:300px;height:150px"></canvas></div>
<div class="block" style="height:60px; width:600px">
<canvas style="height:30px"></canvas><canvas style="height:30px;margin-left:480px"></canvas><canvas style="height:30px"></canvas><canvas style="height:30px;margin-left:480px"></canvas></div>
<br clear=all>
<br clear=all>
<div class="block" style="height:60px; width:600px; white-space:pre">
<span style="display:inline-block; height:60px; margin-top:-90px"><canvas style="background:tan; vertical-align:bottom"></canvas><canvas style="background:black; vertical-align:bottom"></canvas></span></div>
</body>
</html>

View File

@ -67,6 +67,9 @@ canvas:nth-child(4n) { background: black; }
<canvas class="end"></canvas>
</div>
<br clear=all>
<br clear=all>
<div class="grid">
<canvas></canvas>
<canvas></canvas>
@ -85,6 +88,9 @@ canvas:nth-child(4n) { background: black; }
<canvas class="end"></canvas>
</div>
<br clear=all>
<br clear=all>
<div class="grid" style="grid: minmax(auto,30px) 30px/auto auto; grid-gap: 0">
<canvas></canvas>
<canvas class="jend"></canvas>

View File

@ -57,10 +57,10 @@ input {
<div class="grid"><input class="vma10 ae" style="width:190px"></div>
<div class="grid"><input class="vmaa ac" style="width:190px"></div>
<div class="grid"><input class="vr vma10" style="width:190px; height:25px"></div>
<div class="grid"><input class="vr vmaa ac" style="width:190px; height:28px"></div>
<div class="grid"><input class="vr p vma10" style="width:182px; height:17px"></div>
<div class="grid"><input class="vr p vmaa ac" style="width:182px; height:20px"></div>
<div class="grid"><input class="vr vma10" style="width:190px;"></div>
<div class="grid"><input class="vr vmaa" style="width:190px;"></div>
<div class="grid"><input class="vr p vma10" style="width:182px;"></div>
<div class="grid"><input class="vr p vmaa" style="width:182px;"></div>
<div class="grid"><input class="mxw m" style="height:20px"></div>
<div class="grid"><input class="mxw hma10 je" style="height:20px"></div>
@ -74,8 +74,8 @@ input {
<div class="grid"><input class="mxh vr hmaa jc" style="width:10px"></div>
<div class="grid"><input class="mxh vr" style="width:198px"></div>
<div class="grid" style="grid:2px/2px; padding:0;"><input style="width:0;height:0"></div>
<div class="grid" style="grid:2px/2px; padding:0;"><input style="width:0;height:0"></div>
<div class="grid" style="grid:auto/auto; padding:0;"><input></div>
<div class="grid" style="grid:auto/auto; padding:0;"><input></div>
</body>
</html>

View File

@ -44,7 +44,7 @@ x { width:32px; height:2px; background:cyan; }
<br>
<div class="grid w4" style="grid:8px 10px 8px / repeat(7, 4px); grid-column-gap:32px; ">
<div class="grid w4" style="grid:8px 10px 8px / repeat(7, 4px); grid-column-gap:32px; width:292px">
<div style="height:8px; width:2px; background:cyan; grid-row:1"></div>
<div style="height:10px; grid-row:2; grid-column: span 7"></div>
<div style="height:8px; grid-row:3"></div>
@ -53,7 +53,7 @@ x { width:32px; height:2px; background:cyan; }
<br>
<div class="grid w4" style="grid:32px 10px 32px / repeat(7, 4px); grid-column-gap:32px; ">
<div class="grid w4" style="grid:32px 10px 32px / repeat(7, 4px); grid-column-gap:32px; width:292px">
<div style="height:32px; width:2px; background:cyan; grid-row:1"></div>
<div style="height:10px; grid-row:2; grid-column: span 7"></div>
<div style="height:32px; grid-row:3"></div>
@ -62,7 +62,7 @@ x { width:32px; height:2px; background:cyan; }
<br>
<div class="grid w8" style="grid:repeat(3, 4px) / repeat(7, 8px); grid-gap:8px; ">
<div class="grid w8" style="grid:4px 10px 4px 2px 2px / repeat(7, 8px); grid-gap:8px; width:152px">
<div style="height:4px; width:2px; background:cyan; grid-row:1"></div>
<div style="height:10px; grid-row:2; grid-column: span 7"></div>
<div style="height:4px; grid-row:3"></div>
@ -71,7 +71,7 @@ x { width:32px; height:2px; background:cyan; }
<br>
<div class="grid" style="grid:repeat(3, 8px) / repeat(7, 32px); grid-gap:16px; ">
<div class="grid" style="grid:8px 10px 8px 2px 2px / repeat(7, 32px); grid-gap:16px; ">
<div style="height:4px; width:2px; background:cyan; grid-row:1"></div>
<div style="height:10px; grid-row:2; grid-column: span 7"></div>
<div style="height:4px; grid-row:3"></div>

View File

@ -25,7 +25,7 @@ x { width:32px; height:2px; background:cyan; }
</head>
<body>
<div class="grid" style="grid:24px 10px 24px / repeat(7, 32px); grid-column-gap: 10px;">
<div class="grid" style="grid: minmax(auto, 24px) minmax(auto, 10px) minmax(auto, 24px) / repeat(7, minmax(auto, 32px)); grid-column-gap: 10px;">
<div style="height:24px; width:2px; background:cyan; grid-row:1"></div>
<div style="height:10px; grid-row:2; grid-column: span 7"></div>
<div style="height:24px; grid-row:3"></div>
@ -34,7 +34,7 @@ x { width:32px; height:2px; background:cyan; }
<br>
<div class="grid w24" style="grid:32px 10px 32px / repeat(7, 24px); grid-column-gap: 10px;">
<div class="grid w24" style="grid: minmax(auto, 32px) minmax(auto, 10px) minmax(auto, 32px) / repeat(7, minmax(auto, 24px)); grid-column-gap: 10px;">
<div style="height:32px; width:2px; background:cyan; grid-row:1"></div>
<div style="height:10px; grid-row:2; grid-column: span 7"></div>
<div style="height:32px; grid-row:3"></div>
@ -43,7 +43,7 @@ x { width:32px; height:2px; background:cyan; }
<br>
<div class="grid w4" style="grid:8px 10px 8px / repeat(7, 4px); grid-column-gap:32px; ">
<div class="grid w4" style="grid: minmax(auto, 8px) minmax(auto, 10px) minmax(auto, 8px) / repeat(7, minmax(auto, 4px)); grid-column-gap:32px; ">
<div style="height:8px; width:2px; background:cyan; grid-row:1"></div>
<div style="height:10px; grid-row:2; grid-column: span 7"></div>
<div style="height:8px; grid-row:3"></div>
@ -52,7 +52,7 @@ x { width:32px; height:2px; background:cyan; }
<br>
<div class="grid w4" style="grid:32px 10px 32px / repeat(7, 4px); grid-column-gap:32px; ">
<div class="grid w4" style="grid: minmax(auto, 32px) minmax(auto, 10px) minmax(auto, 32px) / repeat(7, minmax(auto, 4px)); grid-column-gap:32px; ">
<div style="height:32px; width:2px; background:cyan; grid-row:1"></div>
<div style="height:10px; grid-row:2; grid-column: span 7"></div>
<div style="height:32px; grid-row:3"></div>
@ -61,7 +61,7 @@ x { width:32px; height:2px; background:cyan; }
<br>
<div class="grid w8" style="grid:repeat(3, 4px) / repeat(7, 8px); grid-gap:8px; ">
<div class="grid w8" style="grid: repeat(3, minmax(auto, 4px)) / repeat(7, minmax(auto, 8px)); grid-gap:8px; ">
<div style="height:4px; width:2px; background:cyan; grid-row:1"></div>
<div style="height:10px; grid-row:2; grid-column: span 7"></div>
<div style="height:4px; grid-row:3"></div>
@ -70,7 +70,7 @@ x { width:32px; height:2px; background:cyan; }
<br>
<div class="grid" style="grid:repeat(3, 8px) / repeat(7, 32px); grid-gap:16px; ">
<div class="grid" style="grid: repeat(3, minmax(auto, 8px)) / repeat(7, minmax(auto, 32px)); grid-gap:16px; ">
<div style="height:4px; width:2px; background:cyan; grid-row:1"></div>
<div style="height:10px; grid-row:2; grid-column: span 7"></div>
<div style="height:4px; grid-row:3"></div>

View File

@ -22,7 +22,9 @@
.sa {align-self:start; justify-self:start}
.an {align-self:start; justify-self:start}
.as {align-self:start; justify-self:start}
.w20 { width: 20px min-width: 0px; }
.w20 { width: 20px; min-width: 0px; }
.w16 { width: 16px; }
.w10 { width: 10px; }
.mw20 { min-width: 20px }
.mw0 { min-width: 0px }
@ -42,14 +44,14 @@
<div class="grid r"><img class="na mxw2"></div>
<pre><!--min-height:20px--></pre>
<div class="grid r"><img class="mh20"></div>
<div class="grid r"><img class="mh20 mxw10"></div>
<div class="grid r"><img class="start mh20"></div>
<div class="grid r"><img class="start mh20 mxw10"></div>
<div class="grid r"><img class="sa mh20"></div>
<div class="grid r"><img class="sa mh20 mxw10"></div>
<div class="grid r"><img class="na mh20"></div>
<div class="grid r"><img class="na mh20 mxw10"></div>
<div class="grid r mh20"><img class="mh20"></div>
<div class="grid r mh20"><img class="mh20 mxw10"></div>
<div class="grid r mh20"><img class="start mh20"></div>
<div class="grid r mh20"><img class="start mh20 mxw10"></div>
<div class="grid r mh20"><img class="sa mh20"></div>
<div class="grid r mh20"><img class="sa mh20 mxw10"></div>
<div class="grid r mh20"><img class="na mh20"></div>
<div class="grid r mh20"><img class="na mh20 mxw10"></div>
<pre><!--min-height:0--></pre>
<div class="grid r"><img class="mh0"></div>
@ -63,34 +65,34 @@
<pre><!----></pre>
<div class="grid"><img></div>
<div class="grid w16"><img></div>
<div class="grid"><img class="mxw2"></div>
<div class="grid"><img class="start"></div>
<div class="grid w16"><img class="start"></div>
<div class="grid"><img class="start mxw2"></div>
<div class="grid"><img class="sa"></div>
<div class="grid w16"><img class="sa"></div>
<div class="grid"><img class="sa mxw2"></div>
<div class="grid"><img class="na"></div>
<div class="grid w16"><img class="na"></div>
<div class="grid"><img class="na mxw2"></div>
<pre><!--min-width:20px--></pre>
<div class="grid"><img class="mw20"></div>
<div class="grid"><img class="mw20 mxh10"></div>
<div class="grid"><img class="start mw20"></div>
<div class="grid"><img class="start mw20 mxh10"></div>
<div class="grid"><img class="sa mw20"></div>
<div class="grid"><img class="sa mw20 mxh10"></div>
<div class="grid"><img class="na mw20"></div>
<div class="grid"><img class="na mw20 mxh10"></div>
<div class="grid mw20"><img class="mw20"></div>
<div class="grid mw20"><img class="mw20 mxh10"></div>
<div class="grid mw20"><img class="start mw20"></div>
<div class="grid mw20"><img class="start mw20 mxh10"></div>
<div class="grid mw20"><img class="sa mw20"></div>
<div class="grid mw20"><img class="sa mw20 mxh10"></div>
<div class="grid mw20"><img class="na mw20"></div>
<div class="grid mw20"><img class="na mw20 mxh10"></div>
<pre><!--min-width:0--></pre>
<div class="grid"><img class="mw0"></div>
<div class="grid"><img class="mw0 mxh10"></div>
<div class="grid"><img class="start mw0"></div>
<div class="grid"><img class="start mw0 mxh10"></div>
<div class="grid"><img class="sa mw0"></div>
<div class="grid"><img class="sa mw0 mxh10"></div>
<div class="grid"><img class="na mw0"></div>
<div class="grid"><img class="na mw0 mxh10"></div>
<div class="grid w16"><img class="mw0"></div>
<div class="grid w10"><img class="mw0 mxh10"></div>
<div class="grid w16"><img class="start mw0"></div>
<div class="grid w10"><img class="start mw0 mxh10"></div>
<div class="grid w16"><img class="sa mw0"></div>
<div class="grid w10"><img class="sa mw0 mxh10"></div>
<div class="grid w16"><img class="na mw0"></div>
<div class="grid w10"><img class="na mw0 mxh10"></div>
<pre><!--width:20px--></pre>
@ -105,36 +107,36 @@
<pre><!--width:20px--></pre>
<div class="grid"><img class="start w20"></div>
<div class="grid"><img class="start w20 mxh10"></div>
<div class="grid"><img class="start w20"></div>
<div class="grid"><img class="start w20 mxh10"></div>
<div class="grid"><img class="sa w20"></div>
<div class="grid"><img class="sa w20 mxh10"></div>
<div class="grid"><img class="na w20"></div>
<div class="grid"><img class="na w20 mxh10"></div>
<div class="grid mw20"><img class="start w20"></div>
<div class="grid mw20"><img class="start w20 mxh10"></div>
<div class="grid mw20"><img class="start w20"></div>
<div class="grid mw20"><img class="start w20 mxh10"></div>
<div class="grid mw20"><img class="sa w20"></div>
<div class="grid mw20"><img class="sa w20 mxh10"></div>
<div class="grid mw20"><img class="na w20"></div>
<div class="grid mw20"><img class="na w20 mxh10"></div>
<pre><!--height:20px--></pre>
<div class="grid r"><img class="h20"></div>
<div class="grid r"><img class="h20 mxw10"></div>
<div class="grid r"><img class="start h20"></div>
<div class="grid r"><img class="start h20 mxw10"></div>
<div class="grid r"><img class="as h20"></div>
<div class="grid r"><img class="as h20 mxw10"></div>
<div class="grid r"><img class="an h20"></div>
<div class="grid r"><img class="an h20 mxw10"></div>
<div class="grid r mh20"><img class="h20"></div>
<div class="grid r mh20"><img class="h20 mxw10"></div>
<div class="grid r mh20"><img class="start h20"></div>
<div class="grid r mh20"><img class="start h20 mxw10"></div>
<div class="grid r mh20"><img class="as h20"></div>
<div class="grid r mh20"><img class="as h20 mxw10"></div>
<div class="grid r mh20"><img class="an h20"></div>
<div class="grid r mh20"><img class="an h20 mxw10"></div>
<pre><!--height:20px--></pre>
<div class="grid"><img class="h20"></div>
<div class="grid mw20"><img class="h20"></div>
<div class="grid"><img class="h20 mxw2"></div>
<div class="grid"><img class="start h20"></div>
<div class="grid"><img class="start h20 mxw10"></div>
<div class="grid"><img class="as h20"></div>
<div class="grid mw20"><img class="start h20"></div>
<div class="grid w10"><img class="start h20 mxw10"></div>
<div class="grid mw20"><img class="as h20"></div>
<div class="grid"><img class="as h20 mxw2"></div>
<div class="grid"><img class="an h20"></div>
<div class="grid"><img class="an h20 mxw10"></div>
<div class="grid mw20"><img class="an h20"></div>
<div class="grid w10"><img class="an h20 mxw10"></div>
<script>
var url = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAIAAACQkWg2AAAACXBIWXMAAAsTAAALEwEAmpwYAAAAEElEQVQoz2NgGAWjYBTAAAADEAABaJFtwwAAAABJRU5ErkJggg%3D%3D";

View File

@ -14,10 +14,10 @@
.grid {
display: inline-grid;
border: 3px solid grey;
grid: 32px / 4px;
grid: minmax(auto, 32px) / minmax(auto, 4px);
margin-right:20px;
}
.r { grid: 4px / 32px; }
.r { grid: minmax(auto, 4px) / minmax(auto, 32px); }
button {
border: 1px solid;

View File

@ -91,37 +91,37 @@ img {
var url = 'data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" width="16px" height="0px"><circle cx="50%" cy="50%" r="50%" fill="pink"/></svg>'
var imgSizes =
[
['8px', '20px'],
['16px', '20px'],
['8px', '20px'],
['16px', '20px'],
['8px', '20px'],
['16px', '20px'],
['8px', '20px'],
['16px', '20px'],
['16px', '20px'],
['16px', '20px'],
['16px', '20px'],
['16px', '20px'],
['8px', '20px'],
['16px', '20px'],
['8px', '20px'],
['16px', '20px'],
['8px', '20px'],
['16px', '20px'],
['8px', '20px'],
['16px', '20px'],
['16px', '20px'],
['16px', '20px'],
['16px', '20px'],
['16px', '20px'],
['8px', '20px'],
['16px', '20px'],
['8px', '20px'],
['16px', '20px'],
['8px', '20px'],
['16px', '20px'],
['8px', '20px'],
['16px', '20px'],
['16px', '20px'],
['16px', '20px'],
['16px', '20px'],
['16px', '20px'],
['16px', '20px'],
['16px', '20px'],
['16px', '20px'],
['16px', '20px'],
['16px', '20px'],
['16px', '20px'],
['16px', '20px'],
['16px', '20px'],
['16px', '20px'],
['16px', '20px'],
['16px', '20px'],
['16px', '20px'],
['16px', '20px'],
['16px', '20px'],
['16px', '20px'],
['16px', '20px'],

View File

@ -91,38 +91,38 @@ img {
var url = 'data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" width="0px" height="16px"><circle cx="50%" cy="50%" r="50%" fill="pink"/></svg>'
var imgSizes =
[
['20px', '8px'],
['20px', '8px'],
['20px', '8px'],
['20px', '8px'],
['20px', '8px'],
['20px', '8px'],
['20px', '8px'],
['20px', '8px'],
['20px', '8px'],
['20px', '8px'],
['20px', '8px'],
['20px', '8px'],
['20px', '8px'],
['20px', '8px'],
['20px', '8px'],
['20px', '8px'],
['20px', '8px'],
['20px', '8px'],
['20px', '8px'],
['20px', '8px'],
['20px', '8px'],
['20px', '8px'],
['20px', '8px'],
['20px', '8px'],
['20px', '8px'],
['20px', '8px'],
['20px', '8px'],
['20px', '8px'],
['20px', '8px'],
['20px', '8px'],
['20px', '8px'],
['20px', '8px'],
['20px', '16px'],
['20px', '16px'],
['20px', '16px'],
['20px', '16px'],
['20px', '16px'],
['20px', '16px'],
['20px', '16px'],
['20px', '16px'],
['20px', '16px'],
['20px', '16px'],
['20px', '16px'],
['20px', '16px'],
['20px', '16px'],
['20px', '16px'],
['20px', '16px'],
['20px', '16px'],
['20px', '16px'],
['20px', '16px'],
['20px', '16px'],
['20px', '16px'],
['20px', '16px'],
['20px', '16px'],
['20px', '16px'],
['20px', '16px'],
['20px', '16px'],
['20px', '16px'],
['20px', '16px'],
['20px', '16px'],
['20px', '16px'],
['20px', '16px'],
['20px', '16px'],
['20px', '16px'],
['20px', '16px'],
['20px', '16px'],
['20px', '16px'],

View File

@ -28,7 +28,7 @@ body,html { color:black; background:white; font:16px/1 monospace; padding:0; mar
<img src="support/lime-2x24.png" style="height:96px; width:4px">
</div>
<div class="grid" style="grid: 8px / 20px">
<div class="grid" style="grid: 8px / 20px; width:24px">
<img src="support/lime-24x2.png" style="width:20px; height:8px">
</div>
<div class="grid" style="grid: 8px / 100px">
@ -45,7 +45,7 @@ body,html { color:black; background:white; font:16px/1 monospace; padding:0; mar
<div class="grid" style="grid: 8px / 100px">
<img src="support/lime-24x2.png" style="justify-self:start; width:24px; height:8px">
</div>
<div class="grid" style="grid: 8px / 10px">
<div class="grid" style="grid: 8px / 10px; width:24px">
<img src="support/lime-24x2.png" style="justify-self:start; width:10px; height:8px">
</div>
@ -64,16 +64,16 @@ body,html { color:black; background:white; font:16px/1 monospace; padding:0; mar
<img src="support/lime-2x24.png" style="align-self:end safe; height:24px; width:10px">
</div>
<div class="grid" style="grid: 4px / 10px">
<div class="grid" style="grid: 4px / 10px; width:24px">
<img src="support/lime-24x2.png" style="justify-self:start unsafe; width:10px; height:4px">
</div>
<div class="grid" style="grid: 4px / 10px; margin-left: 40px">
<div class="grid" style="grid: 4px / 10px; margin-left: 40px; width:24px">
<img src="support/lime-24x2.png" style="justify-self:start safe; width:10px; height:4px">
</div>
<div class="grid" style="grid: 4px / 10px; margin-left: 40px">
<div class="grid" style="grid: 4px / 10px; margin-left: 40px; width:24px">
<img src="support/lime-24x2.png" style="justify-self:end unsafe; width:10px; height:4px">
</div>
<div class="grid" style="grid: 4px / 10px; margin-left: 80px">
<div class="grid" style="grid: 4px / 10px; margin-left: 80px; width:24px">
<img src="support/lime-24x2.png" style="justify-self:end safe; width:10px; height:4px">
</div>
@ -88,7 +88,7 @@ body,html { color:black; background:white; font:16px/1 monospace; padding:0; mar
<img src="support/lime-2x24.png" style="height:96px; width:4px">
</div>
<div class="grid" style="grid: 8px / 20px">
<div class="grid" style="grid: 8px / 20px; width:24px">
<img src="support/lime-24x2.png" style="width:20px; height:8px">
</div>
<div class="grid" style="grid: 8px / 100px">
@ -105,7 +105,7 @@ body,html { color:black; background:white; font:16px/1 monospace; padding:0; mar
<div class="grid" style="grid: 8px / 100px">
<img src="support/lime-24x2.png" style="justify-self:start; width:24px; height:8px">
</div>
<div class="grid" style="grid: 8px / 10px">
<div class="grid" style="grid: 8px / 10px; width:24px">
<img src="support/lime-24x2.png" style="justify-self:start; width:10px; height:8px">
</div>
@ -124,16 +124,16 @@ body,html { color:black; background:white; font:16px/1 monospace; padding:0; mar
<img src="support/lime-2x24.png" style="align-self:end safe; height:24px; width:10px">
</div>
<div class="grid" style="grid: 4px / 10px">
<div class="grid" style="grid: 4px / 10px; width:24px">
<img src="support/lime-24x2.png" style="justify-self:start unsafe; width:10px; height:4px">
</div>
<div class="grid" style="grid: 4px / 10px; margin-left: 40px">
<div class="grid" style="grid: 4px / 10px; margin-left: 40px; width:24px">
<img src="support/lime-24x2.png" style="justify-self:start safe; width:10px; height:4px">
</div>
<div class="grid" style="grid: 4px / 10px; margin-left: 40px">
<div class="grid" style="grid: 4px / 10px; margin-left: 40px; width:24px">
<img src="support/lime-24x2.png" style="justify-self:end unsafe; width:10px; height:4px">
</div>
<div class="grid" style="grid: 4px / 10px; margin-left: 80px">
<div class="grid" style="grid: 4px / 10px; margin-left: 80px; width:24px">
<img src="support/lime-24x2.png" style="justify-self:end safe; width:10px; height:4px">
</div>

View File

@ -23,59 +23,59 @@ body,html { color:black; background:white; font:16px/1 monospace; padding:0; mar
</head>
<body>
<div class="grid" style="grid: 96px / 20px">
<div class="grid" style="grid: minmax(auto, 96px) / minmax(auto, 20px)">
<img src="support/lime-2x24.png">
</div>
<div class="grid" style="grid: 96px / 4px">
<div class="grid" style="grid: minmax(auto, 96px) / minmax(auto, 4px)">
<img src="support/lime-2x24.png">
</div>
<div class="grid" style="grid: 8px / 20px">
<div class="grid" style="grid: minmax(auto, 8px) / minmax(auto, 20px)">
<img src="support/lime-24x2.png">
</div>
<div class="grid" style="grid: 8px / 100px">
<div class="grid" style="grid: minmax(auto, 8px) / minmax(auto, 100px)">
<img src="support/lime-24x2.png">
</div>
<div class="grid" style="grid: 96px / 10px">
<div class="grid" style="grid: minmax(auto, 96px) / minmax(auto, 10px)">
<img src="support/lime-2x24.png" style="align-self:start">
</div>
<div class="grid" style="grid: 96px / 4px">
<div class="grid" style="grid: minmax(auto, 96px) / minmax(auto, 4px)">
<img src="support/lime-2x24.png" style="align-self:start">
</div>
<div class="grid" style="grid: 8px / 100px">
<div class="grid" style="grid: minmax(auto, 8px) / minmax(auto, 100px)">
<img src="support/lime-24x2.png" style="justify-self:start">
</div>
<div class="grid" style="grid: 8px / 10px">
<div class="grid" style="grid: minmax(auto, 8px) / minmax(auto, 10px)">
<img src="support/lime-24x2.png" style="justify-self:start">
</div>
<br>
<div class="grid" style="grid: 96px / 10px">
<div class="grid" style="grid: minmax(auto, 96px) / minmax(auto, 10px)">
<img src="support/lime-2x24.png" style="align-self:start safe;">
</div>
<div class="grid" style="grid: 96px / 10px">
<div class="grid" style="grid: minmax(auto, 96px) / minmax(auto, 10px)">
<img src="support/lime-2x24.png" style="align-self:start unsafe;">
</div>
<div class="grid" style="grid: 96px / 10px">
<div class="grid" style="grid: minmax(auto, 96px) / minmax(auto, 10px)">
<img src="support/lime-2x24.png" style="align-self:end safe;">
</div>
<div class="grid" style="grid: 96px / 10px">
<div class="grid" style="grid: minmax(auto, 96px) / minmax(auto, 10px)">
<img src="support/lime-2x24.png" style="align-self:end unsafe;">
</div>
<div class="grid" style="grid: 4px / 10px">
<div class="grid" style="grid: minmax(auto, 4px) / minmax(auto, 10px)">
<img src="support/lime-24x2.png" style="justify-self:start safe">
</div>
<div class="grid" style="grid: 4px / 10px; margin-left: 40px">
<div class="grid" style="grid: minmax(auto, 4px) / minmax(auto, 10px); margin-left: 40px">
<img src="support/lime-24x2.png" style="justify-self:start unsafe">
</div>
<div class="grid" style="grid: 4px / 10px; margin-left: 40px">
<div class="grid" style="grid: minmax(auto, 4px) / minmax(auto, 10px); margin-left: 40px">
<img src="support/lime-24x2.png" style="justify-self:end safe">
</div>
<div class="grid" style="grid: 4px / 10px; margin-left: 80px">
<div class="grid" style="grid: minmax(auto, 4px) / minmax(auto, 10px); margin-left: 80px">
<img src="support/lime-24x2.png" style="justify-self:end unsafe">
</div>
@ -83,59 +83,59 @@ body,html { color:black; background:white; font:16px/1 monospace; padding:0; mar
<div class="vertical-tests">
<div class="grid" style="grid: 96px / 20px">
<div class="grid" style="grid: minmax(auto, 96px) / minmax(auto, 20px)">
<img src="support/lime-2x24.png">
</div>
<div class="grid" style="grid: 96px / 4px">
<div class="grid" style="grid: minmax(auto, 96px) / minmax(auto, 4px)">
<img src="support/lime-2x24.png">
</div>
<div class="grid" style="grid: 8px / 20px">
<div class="grid" style="grid: minmax(auto, 8px) / minmax(auto, 20px)">
<img src="support/lime-24x2.png">
</div>
<div class="grid" style="grid: 8px / 100px">
<div class="grid" style="grid: minmax(auto, 8px) / minmax(auto, 100px)">
<img src="support/lime-24x2.png">
</div>
<div class="grid" style="grid: 96px / 10px">
<div class="grid" style="grid: minmax(auto, 96px) / minmax(auto, 10px)">
<img src="support/lime-2x24.png" style="align-self:start">
</div>
<div class="grid" style="grid: 96px / 4px">
<div class="grid" style="grid: minmax(auto, 96px) / minmax(auto, 4px)">
<img src="support/lime-2x24.png" style="align-self:start">
</div>
<div class="grid" style="grid: 8px / 100px">
<div class="grid" style="grid: minmax(auto, 8px) / minmax(auto, 100px)">
<img src="support/lime-24x2.png" style="justify-self:start">
</div>
<div class="grid" style="grid: 8px / 10px">
<div class="grid" style="grid: minmax(auto, 8px) / minmax(auto, 10px)">
<img src="support/lime-24x2.png" style="justify-self:start">
</div>
<br>
<div class="grid" style="grid: 96px / 10px">
<div class="grid" style="grid: minmax(auto, 96px) / minmax(auto, 10px)">
<img src="support/lime-2x24.png" style="align-self:start safe;">
</div>
<div class="grid" style="grid: 96px / 10px">
<div class="grid" style="grid: minmax(auto, 96px) / minmax(auto, 10px)">
<img src="support/lime-2x24.png" style="align-self:start unsafe;">
</div>
<div class="grid" style="grid: 96px / 10px">
<div class="grid" style="grid: minmax(auto, 96px) / minmax(auto, 10px)">
<img src="support/lime-2x24.png" style="align-self:end safe;">
</div>
<div class="grid" style="grid: 96px / 10px">
<div class="grid" style="grid: minmax(auto, 96px) / minmax(auto, 10px)">
<img src="support/lime-2x24.png" style="align-self:end unsafe;">
</div>
<div class="grid" style="grid: 4px / 10px">
<div class="grid" style="grid: minmax(auto, 4px) / minmax(auto, 10px)">
<img src="support/lime-24x2.png" style="justify-self:start safe">
</div>
<div class="grid" style="grid: 4px / 10px; margin-left: 40px">
<div class="grid" style="grid: minmax(auto, 4px) / minmax(auto, 10px); margin-left: 40px">
<img src="support/lime-24x2.png" style="justify-self:start unsafe">
</div>
<div class="grid" style="grid: 4px / 10px; margin-left: 40px">
<div class="grid" style="grid: minmax(auto, 4px) / minmax(auto, 10px); margin-left: 40px">
<img src="support/lime-24x2.png" style="justify-self:end safe">
</div>
<div class="grid" style="grid: 4px / 10px; margin-left: 80px">
<div class="grid" style="grid: minmax(auto, 4px) / minmax(auto, 10px); margin-left: 80px">
<img src="support/lime-24x2.png" style="justify-self:end unsafe">
</div>

View File

@ -17,6 +17,10 @@ body,html { color:black; background:white; font:16px/1 monospace; padding:0; mar
align-items: start;
justify-items: start;
}
img {
min-width: 0;
min-height: 0;
}
.vertical-tests div { vertical-align:bottom }
</style>
</head>
@ -46,7 +50,7 @@ body,html { color:black; background:white; font:16px/1 monospace; padding:0; mar
<div class="grid" style="grid: 8px / 100px">
<img src="support/lime-24x2.png" style="justify-self:start; width:24px; height:8px">
</div>
<div class="grid" style="grid: 8px / 10px">
<div class="grid" style="grid: 8px / 10px; width:24px">
<img src="support/lime-24x2.png" style="justify-self:start; width:10px; height:8px">
</div>
@ -55,28 +59,30 @@ body,html { color:black; background:white; font:16px/1 monospace; padding:0; mar
<div class="grid" style="grid: 96px / 20px">
<img src="support/lime-2x24.png" style="width:20px; height:96px">
</div>
<div class="grid" style="grid: 96px / 4px">
<div class="grid" style="grid: 96px / 4px; width:6px">
<img src="support/lime-2x24.png" style="width:6px; height:96px">
</div>
<div class="grid" style="grid: 8px / 20px">
<div class="grid" style="grid: 8px / 20px; width:24px">
<img src="support/lime-24x2.png" style="width:20px; height:8px">
</div>
<div class="grid" style="grid: 8px / 100px">
<div class="grid" style="grid: 8px / 100px; width:120px; height:10px">
<img src="support/lime-24x2.png" style="width:100px; height:10px">
</div>
<div class="grid" style="grid: 48px / 6px">
<div class="grid" style="grid: 48px / 6px; width:7px; height:80px">
<img src="support/lime-2x24.png" style="align-self:start; width:6px; height:80px">
</div>
<div class="grid" style="grid: 96px / 4px">
<!--
<div class="grid" style="grid: minmax(auto, 96px) / minmax(auto, 6px)">
<img src="support/lime-2x24.png" style="align-self:start; width:4px; height:72px">
</div>
<div class="grid" style="grid: 8px / 100px">
<img src="support/lime-24x2.png" style="justify-self:start; width:98px; height:calc(2px * (98 / 24))">
<div class="grid" style="grid: 4px / 100px">
<img src="support/lime-24x2.png" style="justify-self:start; width:72px; height:4px">
</div>
<div class="grid" style="grid: 4px / 10px">
-->
<div class="grid" style="grid: 4px / 10px; width:72px">
<img src="support/lime-24x2.png" style="justify-self:start; width:72px; height:4px">
</div>
@ -108,7 +114,7 @@ body,html { color:black; background:white; font:16px/1 monospace; padding:0; mar
<div class="grid" style="grid: 8px / 100px">
<img src="support/lime-24x2.png" style="justify-self:start; width:24px; height:8px">
</div>
<div class="grid" style="grid: 8px / 10px">
<div class="grid" style="grid: 8px / 10px; width:24px">
<img src="support/lime-24x2.png" style="justify-self:start; width:10px; height:8px">
</div>
@ -117,28 +123,30 @@ body,html { color:black; background:white; font:16px/1 monospace; padding:0; mar
<div class="grid" style="grid: 96px / 20px">
<img src="support/lime-2x24.png" style="width:20px; height:96px">
</div>
<div class="grid" style="grid: 96px / 4px">
<div class="grid" style="grid: 96px / 4px; width:6px">
<img src="support/lime-2x24.png" style="width:6px; height:96px">
</div>
<div class="grid" style="grid: 8px / 20px">
<div class="grid" style="grid: 8px / 20px; width:24px">
<img src="support/lime-24x2.png" style="width:20px; height:8px">
</div>
<div class="grid" style="grid: 8px / 100px">
<div class="grid" style="grid: 8px / 100px; width:120px; height:10px">
<img src="support/lime-24x2.png" style="width:100px; height:10px">
</div>
<div class="grid" style="grid: 48px / 6px">
<div class="grid" style="grid: 48px / 6px; width:7px; height:80px">
<img src="support/lime-2x24.png" style="align-self:start; width:6px; height:80px">
</div>
<div class="grid" style="grid: 96px / 4px">
<!--
<div class="grid" style="grid: minmax(auto, 96px) / minmax(auto, 6px)">
<img src="support/lime-2x24.png" style="align-self:start; width:4px; height:72px">
</div>
<div class="grid" style="grid: 8px / 100px">
<img src="support/lime-24x2.png" style="justify-self:start; width:98px; height:calc(2px * (98 / 24))">
<div class="grid" style="grid: 4px / 100px">
<img src="support/lime-24x2.png" style="justify-self:start; width:72px; height:4px">
</div>
<div class="grid" style="grid: 4px / 10px">
-->
<div class="grid" style="grid: 4px / 10px; width:72px">
<img src="support/lime-24x2.png" style="justify-self:start; width:72px; height:4px">
</div>

View File

@ -24,61 +24,63 @@ body,html { color:black; background:white; font:16px/1 monospace; padding:0; mar
</head>
<body>
<div class="grid" style="grid: 96px / 20px">
<div class="grid" style="grid: minmax(auto, 96px) / minmax(auto, 20px)">
<img src="support/lime-2x24.png" style="max-width:4px">
</div>
<div class="grid" style="grid: 96px / 4px">
<div class="grid" style="grid: minmax(auto, 96px) / minmax(auto, 4px)">
<img src="support/lime-2x24.png" style="max-height:12px">
</div>
<div class="grid" style="grid: 8px / 20px">
<div class="grid" style="grid: minmax(auto, 8px) / minmax(auto, 20px)">
<img src="support/lime-24x2.png" style="max-width:12px">
</div>
<div class="grid" style="grid: 8px / 100px">
<div class="grid" style="grid: minmax(auto, 8px) / minmax(auto, 100px)">
<img src="support/lime-24x2.png" style="max-height:6px">
</div>
<div class="grid" style="grid: 96px / 20px">
<div class="grid" style="grid: minmax(auto, 96px) / minmax(auto, 20px)">
<img src="support/lime-2x24.png" style="align-self:start; max-height:48px">
</div>
<div class="grid" style="grid: 96px / 4px">
<div class="grid" style="grid: minmax(auto, 96px) / minmax(auto, 4px)">
<img src="support/lime-2x24.png" style="align-self:start; max-height:12px">
</div>
<div class="grid" style="grid: 8px / 100px">
<div class="grid" style="grid: minmax(auto, 8px) / minmax(auto, 100px)">
<img src="support/lime-24x2.png" style="justify-self:start; max-width:48px">
</div>
<div class="grid" style="grid: 8px / 10px">
<div class="grid" style="grid: minmax(auto, 8px) / minmax(auto, 10px)">
<img src="support/lime-24x2.png" style="justify-self:start; max-width:48px">
</div>
<br>
<div class="grid" style="grid: 96px / 20px">
<div class="grid" style="grid: minmax(auto, 96px) / minmax(auto, 20px)">
<img src="support/lime-2x24.png" style="min-width:10px">
</div>
<div class="grid" style="grid: 96px / 4px">
<div class="grid" style="grid: minmax(auto, 96px) / minmax(auto, 4px)">
<img src="support/lime-2x24.png" style="min-width:6px">
</div>
<div class="grid" style="grid: 8px / 20px">
<div class="grid" style="grid: minmax(auto, 8px) / minmax(auto, 20px)">
<img src="support/lime-24x2.png" style="min-height:2px">
</div>
<div class="grid" style="grid: 8px / 100px">
<div class="grid" style="grid: minmax(auto, 8px) / minmax(auto, 100px)">
<img src="support/lime-24x2.png" style="min-height:10px">
</div>
<div class="grid" style="grid: 48px / 6px">
<div class="grid" style="grid: minmax(auto, 48px) / minmax(auto, 6px)">
<img src="support/lime-2x24.png" style="align-self:start; min-height:80px">
</div>
<div class="grid" style="grid: 96px / 4px">
<!--
<div class="grid" style="grid: minmax(auto, 96px) / minmax(auto, 4px)">
<img src="support/lime-2x24.png" style="align-self:start; min-height:72px">
</div>
<div class="grid" style="grid: 8px / 100px">
<img src="support/lime-24x2.png" style="justify-self:start; min-width:98px">
<div class="grid" style="grid: minmax(auto, 4px) / minmax(auto, 100px)">
<img src="support/lime-24x2.png" style="justify-self:start; min-width:72px">
</div>
<div class="grid" style="grid: 4px / 10px">
-->
<div class="grid" style="grid: minmax(auto, 4px) / minmax(auto, 10px)">
<img src="support/lime-24x2.png" style="justify-self:start; min-width:72px">
</div>
@ -86,61 +88,63 @@ body,html { color:black; background:white; font:16px/1 monospace; padding:0; mar
<div class="vertical-tests">
<div class="grid" style="grid: 96px / 20px">
<div class="grid" style="grid: minmax(auto, 96px) / minmax(auto, 20px)">
<img src="support/lime-2x24.png" style="max-width:4px">
</div>
<div class="grid" style="grid: 96px / 4px">
<div class="grid" style="grid: minmax(auto, 96px) / minmax(auto, 4px)">
<img src="support/lime-2x24.png" style="max-height:12px">
</div>
<div class="grid" style="grid: 8px / 20px">
<div class="grid" style="grid: minmax(auto, 8px) / minmax(auto, 20px)">
<img src="support/lime-24x2.png" style="max-width:12px">
</div>
<div class="grid" style="grid: 8px / 100px">
<div class="grid" style="grid: minmax(auto, 8px) / minmax(auto, 100px)">
<img src="support/lime-24x2.png" style="max-height:6px">
</div>
<div class="grid" style="grid: 96px / 20px">
<div class="grid" style="grid: minmax(auto, 96px) / minmax(auto, 20px)">
<img src="support/lime-2x24.png" style="align-self:start; max-height:48px">
</div>
<div class="grid" style="grid: 96px / 4px">
<div class="grid" style="grid: minmax(auto, 96px) / minmax(auto, 4px)">
<img src="support/lime-2x24.png" style="align-self:start; max-height:12px">
</div>
<div class="grid" style="grid: 8px / 100px">
<div class="grid" style="grid: minmax(auto, 8px) / minmax(auto, 100px)">
<img src="support/lime-24x2.png" style="justify-self:start; max-width:48px">
</div>
<div class="grid" style="grid: 8px / 10px">
<div class="grid" style="grid: minmax(auto, 8px) / minmax(auto, 10px)">
<img src="support/lime-24x2.png" style="justify-self:start; max-width:48px">
</div>
<br>
<div class="grid" style="grid: 96px / 20px">
<div class="grid" style="grid: minmax(auto, 96px) / minmax(auto, 20px)">
<img src="support/lime-2x24.png" style="min-width:10px">
</div>
<div class="grid" style="grid: 96px / 4px">
<div class="grid" style="grid: minmax(auto, 96px) / minmax(auto, 4px)">
<img src="support/lime-2x24.png" style="min-width:6px">
</div>
<div class="grid" style="grid: 8px / 20px">
<div class="grid" style="grid: minmax(auto, 8px) / minmax(auto, 20px)">
<img src="support/lime-24x2.png" style="min-height:2px">
</div>
<div class="grid" style="grid: 8px / 100px">
<div class="grid" style="grid: minmax(auto, 8px) / minmax(auto, 100px)">
<img src="support/lime-24x2.png" style="min-height:10px">
</div>
<div class="grid" style="grid: 48px / 6px">
<div class="grid" style="grid: minmax(auto, 48px) / minmax(auto, 6px)">
<img src="support/lime-2x24.png" style="align-self:start; min-height:80px">
</div>
<div class="grid" style="grid: 96px / 4px">
<!--
<div class="grid" style="grid: minmax(auto, 96px) / minmax(auto, 4px)">
<img src="support/lime-2x24.png" style="align-self:start; min-height:72px">
</div>
<div class="grid" style="grid: 8px / 100px">
<img src="support/lime-24x2.png" style="justify-self:start; min-width:98px">
<div class="grid" style="grid: minmax(auto, 4px) / minmax(auto, 100px)">
<img src="support/lime-24x2.png" style="justify-self:start; min-width:72px">
</div>
<div class="grid" style="grid: 4px / 10px">
-->
<div class="grid" style="grid: minmax(auto, 4px) / minmax(auto, 10px)">
<img src="support/lime-24x2.png" style="justify-self:start; min-width:72px">
</div>

View File

@ -13,7 +13,7 @@ body,html { color:black; background:white; font:16px/1 monospace; padding:0; mar
.grid {
display: grid;
float: left;
grid: auto-flow auto / 10px 30px 10px 30px 10px 30px 10px 30px auto auto auto auto;
grid: auto-flow auto / 10px 30px 10px 30px 10px 30px 10px 30px 26px 26px 26px 26px;
grid-gap: 5px;
border:1px solid;
align-items: stretch;
@ -64,7 +64,7 @@ img {
<img class="end">
</div>
<div class="grid">
<div class="grid" style="grid-template-columns: 10px 30px 10px 30px 10px 30px 10px 30px 26px 16px">
<img>
<img>
<img class="jend">
@ -101,9 +101,9 @@ var imgSizes =
['28px', '20px'],
['8px', '20px'],
['16px', '20px'],
['24px', '20px'],
['16px', '20px'],
['16px', '20px'],
['16px', '20px'],
['24px', '20px'],
['16px', '20px'],
['8px', '20px'],
['28px', '20px'],
@ -113,9 +113,9 @@ var imgSizes =
['28px', '20px'],
['8px', '20px'],
['16px', '20px'],
['24px', '20px'],
['16px', '20px'],
['16px', '20px'],
['16px', '20px'],
['24px', '20px'],
['16px', '20px'],
['8px', '20px'],
['28px', '20px'],
@ -132,7 +132,7 @@ var imgSizes =
['16px', '20px'],
['16px', '20px'],
['16px', '20px'],
['16px', '20px'],
['16px', '20px']
];
var imgs = document.querySelectorAll('img');
for (var i = 0; i < imgs.length; ++i) {

View File

@ -15,7 +15,7 @@ body,html { color:black; background:white; font:16px/1 monospace; padding:0; mar
.grid {
display: grid;
float: left;
grid: auto-flow auto / 10px 30px 10px 30px 10px 30px 10px 30px auto auto auto auto;
grid: auto-flow auto / minmax(auto, 10px) minmax(auto, 30px) minmax(auto, 10px) minmax(auto, 30px) minmax(auto, 10px) minmax(auto, 30px) minmax(auto, 10px) minmax(auto, 30px) auto auto auto auto;
grid-gap: 5px;
border:1px solid;
align-items: stretch;

View File

@ -13,7 +13,7 @@ body,html { color:black; background:white; font:16px/1 monospace; padding:0; mar
.grid {
display: grid;
float: left;
grid: auto-flow 10px / 10px 30px 10px 30px 10px 30px 10px 30px auto auto auto auto;
grid: auto-flow 18px / 22px 30px 22px 30px 22px 30px 22px 30px 22px 22px 22px 22px;
grid-gap: 5px;
border:1px solid;
}
@ -62,7 +62,7 @@ img {
<img class="end">
</div>
<div class="grid">
<div class="grid" style="grid-template-columns: 22px 30px 22px 30px 22px 30px 22px 30px 15px">
<img>
<img>
<img class="jend">
@ -91,38 +91,38 @@ img {
var url = 'data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" width="0px" height="16px"><circle cx="50%" cy="50%" r="50%" fill="pink"/></svg>'
var imgSizes =
[
['20px', '8px'],
['20px', '8px'],
['20px', '8px'],
['20px', '8px'],
['20px', '8px'],
['20px', '8px'],
['20px', '8px'],
['20px', '8px'],
['20px', '8px'],
['20px', '8px'],
['20px', '8px'],
['20px', '8px'],
['20px', '8px'],
['20px', '8px'],
['20px', '8px'],
['20px', '8px'],
['20px', '8px'],
['20px', '8px'],
['20px', '8px'],
['20px', '8px'],
['20px', '8px'],
['20px', '8px'],
['20px', '8px'],
['20px', '8px'],
['20px', '8px'],
['20px', '8px'],
['20px', '8px'],
['20px', '8px'],
['20px', '8px'],
['20px', '8px'],
['20px', '8px'],
['20px', '8px'],
['20px', '16px'],
['20px', '16px'],
['20px', '16px'],
['20px', '16px'],
['20px', '16px'],
['20px', '16px'],
['20px', '16px'],
['20px', '16px'],
['20px', '16px'],
['20px', '16px'],
['20px', '16px'],
['20px', '16px'],
['20px', '16px'],
['20px', '16px'],
['20px', '16px'],
['20px', '16px'],
['20px', '16px'],
['20px', '16px'],
['20px', '16px'],
['20px', '16px'],
['20px', '16px'],
['20px', '16px'],
['20px', '16px'],
['20px', '16px'],
['20px', '16px'],
['20px', '16px'],
['20px', '16px'],
['20px', '16px'],
['20px', '16px'],
['20px', '16px'],
['20px', '16px'],
['20px', '16px'],
['20px', '16px'],
['20px', '16px'],
['20px', '16px'],

View File

@ -15,7 +15,7 @@ body,html { color:black; background:white; font:16px/1 monospace; padding:0; mar
.grid {
display: grid;
float: left;
grid: auto-flow 10px / 10px 30px 10px 30px 10px 30px 10px 30px auto auto auto auto;
grid: auto-flow auto / minmax(auto, 10px) minmax(auto, 30px) minmax(auto, 10px) minmax(auto, 30px) minmax(auto, 10px) minmax(auto, 30px) minmax(auto, 10px) minmax(auto, 30px) auto auto auto auto;
grid-gap: 5px;
border:1px solid;
}

View File

@ -26,11 +26,15 @@ iframe {
background: lightgrey;
}
.w20 { width: 20px min-width: 0px; }
.w20 { width: 20px; min-width: 0px; }
.w22 { width: 22px; }
.mw20 { min-width: 20px }
.mw0 { min-width: 0px }
.wi { width:302px }
.h20 { height: 20px; min-height: 0px; }
.h22 { height: 22px; min-height: 0px; }
.h32 { height: 32px; min-height: 0px; }
.mh20 { min-height: 20px }
.mh0 { min-height: 0px }
@ -38,63 +42,63 @@ iframe {
</head>
<body>
<div class="grid r"><iframe></iframe></div>
<div class="grid r"><iframe class="start"></iframe></div>
<div class="grid r"><iframe class="sa"></iframe></div>
<div class="grid r wi"><iframe></iframe></div>
<div class="grid r wi"><iframe class="start"></iframe></div>
<div class="grid r wi"><iframe class="sa"></iframe></div>
<div class="grid r"><iframe class="sa mxw10"></iframe></div>
<div class="grid r"><iframe class="na"></iframe></div>
<div class="grid r wi"><iframe class="na"></iframe></div>
<div class="grid r"><iframe class="na mxw2"></iframe></div>
<pre><!--min-height:20px--></pre>
<div class="grid r" style="margin-right:0"><iframe class="mh20"></iframe></div>
<div class="grid r"><iframe class="mh20 mxw10"></iframe></div>
<div class="grid r"><iframe class="start mh20"></iframe></div>
<div class="grid r"><iframe class="start mh20 mxw10"></iframe></div>
<div class="grid r"><iframe class="sa mh20"></iframe></div>
<div class="grid r"><iframe class="sa mh20 mxw10"></iframe></div>
<div class="grid r"><iframe class="na mh20"></iframe></div>
<div class="grid r"><iframe class="na mh20 mxw10"></iframe></div>
<div class="grid h22 r wi" style="margin-right:0"><iframe class="h20"></iframe></div>
<div class="grid h22 r"><iframe class="mh20 mxw10"></iframe></div>
<div class="grid h22 r wi"><iframe class="start mh20"></iframe></div>
<div class="grid h22 r"><iframe class="start mh20 mxw10"></iframe></div>
<div class="grid h22 r wi"><iframe class="sa mh20"></iframe></div>
<div class="grid h22 r"><iframe class="sa mh20 mxw10"></iframe></div>
<div class="grid h22 r wi"><iframe class="na mh20"></iframe></div>
<div class="grid h22 r"><iframe class="na mh20 mxw10"></iframe></div>
<pre><!--min-height:0--></pre>
<div class="grid r"><iframe class="mh0"></iframe></div>
<div class="grid r wi"><iframe class="mh0"></iframe></div>
<div class="grid r"><iframe class="mh0 mxw10"></iframe></div>
<div class="grid r"><iframe class="start mh0"></iframe></div>
<div class="grid r wi"><iframe class="start mh0"></iframe></div>
<div class="grid r"><iframe class="start mh0 mxw10"></iframe></div>
<div class="grid r"><iframe class="sa mh0"></iframe></div>
<div class="grid r wi"><iframe class="sa mh0"></iframe></div>
<div class="grid r"><iframe class="sa mh0 mxw10"></iframe></div>
<div class="grid r"><iframe class="na mh0"></iframe></div>
<div class="grid r wi"><iframe class="na mh0"></iframe></div>
<div class="grid r"><iframe class="na mh0 mxw2"></iframe></div>
<pre><!----></pre>
<div class="grid"><iframe></iframe></div>
<div class="grid wi"><iframe></iframe></div>
<div class="grid"><iframe class="mxw2"></iframe></div>
<div class="grid"><iframe class="start"></iframe></div>
<div class="grid wi"><iframe class="start"></iframe></div>
<div class="grid"><iframe class="start mxw2"></iframe></div>
<div class="grid"><iframe class="sa"></iframe></div>
<div class="grid wi"><iframe class="sa"></iframe></div>
<div class="grid"><iframe class="sa mxw2"></iframe></div>
<div class="grid"><iframe class="na"></iframe></div>
<div class="grid wi"><iframe class="na"></iframe></div>
<div class="grid"><iframe class="na mxw2"></iframe></div>
<pre><!--min-width:20px--></pre>
<div class="grid"><iframe class="mw20"></iframe></div>
<div class="grid"><iframe class="mw20 mxh10"></iframe></div>
<div class="grid"><iframe class="start mw20"></iframe></div>
<div class="grid" style="margin-top:5px"><iframe class="start mw20 mxh10"></iframe></div>
<div class="grid" style="margin-top:10px"><iframe class="sa mw20"></iframe></div>
<div class="grid" style="margin-top:25px"><iframe class="sa mw20 mxh10"></iframe></div>
<div class="grid"><iframe class="na mw20"></iframe></div>
<div class="grid" style="margin-top:5px"><iframe class="na mw20 mxh10 mxw10"></iframe></div>
<div class="grid wi"><iframe class="mw20"></iframe></div>
<div class="grid wi"><iframe class="mw20 mxh10"></iframe></div>
<div class="grid wi"><iframe class="start mw20"></iframe></div>
<div class="grid wi" style="margin-top:5px"><iframe class="start mw20 mxh10"></iframe></div>
<div class="grid wi" style="margin-top:10px"><iframe class="sa mw20"></iframe></div>
<div class="grid wi" style="margin-top:25px"><iframe class="sa mw20 mxh10"></iframe></div>
<div class="grid wi"><iframe class="na mw20"></iframe></div>
<div class="grid w22" style="margin-top:5px"><iframe class="na mw20 mxh10 mxw10"></iframe></div>
<pre><!--min-width:0--></pre>
<div class="grid"><iframe class="mw0"></iframe></div>
<div class="grid"><iframe class="mw0 mxh10"></iframe></div>
<div class="grid"><iframe class="start mw0"></iframe></div>
<div class="grid" style="margin-top:5px"><iframe class="start mw0 mxh10"></iframe></div>
<div class="grid" style="margin-top:10px"><iframe class="sa mw0"></iframe></div>
<div class="grid" style="margin-top:25px"><iframe class="sa mw0 mxh10 mxw10"></iframe></div>
<div class="grid"><iframe class="na mw0 mxw10"></iframe></div>
<div class="grid" style="margin-top:5px"><iframe class="na mw0 mxh10"></iframe></div>
<div class="grid wi"><iframe class="mw0"></iframe></div>
<div class="grid wi"><iframe class="mw0 mxh10"></iframe></div>
<div class="grid wi"><iframe class="start mw0"></iframe></div>
<div class="grid wi" style="margin-top:5px"><iframe class="start mw0 mxh10"></iframe></div>
<div class="grid wi" style="margin-top:10px"><iframe class="sa mw0"></iframe></div>
<div class="grid " style="margin-top:25px; width:12px"><iframe class="sa mw0 mxh10 mxw10"></iframe></div>
<div class="grid " style="width:12px"><iframe class="na mw0 mxw10"></iframe></div>
<div class="grid wi" style="margin-top:5px"><iframe class="na mw0 mxh10"></iframe></div>
<pre><!--width:20px--></pre>
@ -109,36 +113,36 @@ iframe {
<pre><!--width:20px--></pre>
<div class="grid"><iframe class="start w20"></iframe></div>
<div class="grid"><iframe class="start w20 mxh10"></iframe></div>
<div class="grid"><iframe class="start w20"></iframe></div>
<div class="grid"><iframe class="start w20 mxh10"></iframe></div>
<div class="grid"><iframe class="sa w20"></iframe></div>
<div class="grid"><iframe class="sa w20 mxh10"></iframe></div>
<div class="grid"><iframe class="na w20"></iframe></div>
<div class="grid"><iframe class="na w20 mxh10"></iframe></div>
<div class="grid w22"><iframe class="start w20"></iframe></div>
<div class="grid w22"><iframe class="start w20 mxh10"></iframe></div>
<div class="grid w22"><iframe class="start w20"></iframe></div>
<div class="grid w22"><iframe class="start w20 mxh10"></iframe></div>
<div class="grid w22"><iframe class="sa w20"></iframe></div>
<div class="grid w22"><iframe class="sa w20 mxh10"></iframe></div>
<div class="grid w22"><iframe class="na w20"></iframe></div>
<div class="grid w22"><iframe class="na w20 mxh10"></iframe></div>
<pre><!--height:20px--></pre>
<div class="grid r"><iframe class="h20"></iframe></div>
<div class="grid r"><iframe class="h20 mxw10"></iframe></div>
<div class="grid r"><iframe class="start h20"></iframe></div>
<div class="grid r"><iframe class="start h20 mxw10"></iframe></div>
<div class="grid r"><iframe class="as h20"></iframe></div>
<div class="grid r"><iframe class="as h20 mxw10"></iframe></div>
<div class="grid r"><iframe class="an h20"></iframe></div>
<div class="grid r"><iframe class="an h20 mxw10"></iframe></div>
<div class="grid h22 r wi"><iframe class="h20"></iframe></div>
<div class="grid h22 r"><iframe class="h20 mxw10"></iframe></div>
<div class="grid h22 r wi"><iframe class="start h20"></iframe></div>
<div class="grid h22 r"><iframe class="start h20 mxw10"></iframe></div>
<div class="grid h22 r wi"><iframe class="as h20"></iframe></div>
<div class="grid h22 r"><iframe class="as h20 mxw10"></iframe></div>
<div class="grid h22 r wi"><iframe class="an h20"></iframe></div>
<div class="grid h22 r"><iframe class="an h20 mxw10"></iframe></div>
<pre><!--height:20px--></pre>
<div class="grid"><iframe class="h20"></iframe></div>
<div class="grid"><iframe class="h20 mxw2"></iframe></div>
<div class="grid"><iframe class="start h20"></iframe></div>
<div class="grid"><iframe class="start h20 mxw10"></iframe></div>
<div class="grid"><iframe class="as h20"></iframe></div>
<div class="grid"><iframe class="as h20 mxw2"></iframe></div>
<div class="grid"><iframe class="an h20"></iframe></div>
<div class="grid"><iframe class="an h20 mxw10"></iframe></div>
<div class="grid h32 wi"><iframe class="h20"></iframe></div>
<div class="grid h32"><iframe class="h20 mxw2"></iframe></div>
<div class="grid h32 wi"><iframe class="start h20"></iframe></div>
<div class="grid h32" style="width:12px"><iframe class="start h20 mxw10"></iframe></div>
<div class="grid h32 wi"><iframe class="as h20"></iframe></div>
<div class="grid h32"><iframe class="as h20 mxw2"></iframe></div>
<div class="grid h32 wi"><iframe class="an h20"></iframe></div>
<div class="grid h32" style="width:12px"><iframe class="an h20 mxw10"></iframe></div>
<script>
var iframeSizes =

View File

@ -14,10 +14,10 @@
.grid {
display: inline-grid;
border: 3px solid grey;
grid: 32px / 4px;
grid: minmax(auto, 32px) / minmax(auto, 4px);
margin-right:20px;
}
.r { grid: 4px / 32px; }
.r { grid: minmax(auto, 4px) / minmax(auto, 32px); }
iframe {
border: 1px solid;

View File

@ -34,8 +34,8 @@ br { clear:both; }
</head>
<body>
<div class="grid"><span class=""><x></x></span></div>
<div class="grid"><span class="m"><x></x></span></div>
<div class="grid"><span class="" style="width:78px"><x></x></span></div>
<div class="grid"><span class="m" style="width:68px"><x></x></span></div>
<div class="grid"><span class="ma" style="margin-left:5px"><x></x></span></div>
<br>

View File

@ -16,8 +16,9 @@
margin-right:20px;
align-items: start;
justify-items: start;
width: 18px;
}
.r { grid: 4px / 32px; }
.r { grid: 4px / 32px; width: 32px;}
table {
border: 1px solid;
@ -35,6 +36,7 @@ t { display:block; width:6px; height:6px; }
.mxw10 { width: 10px }
.mw20 { width: 20px }
.wfill { width:32px }
.w6 { width: 6px }
.h20 { height: 20px }
.mxh10 { height: 10px }
@ -95,46 +97,46 @@ t { display:block; width:6px; height:6px; }
<pre><!----></pre>
<div class="grid"><table cellpadding=0 cellspacing=0 class="hfill"><caption><x></x></caption><td><t></t></td></table></div>
<div class="grid"><table cellpadding=0 cellspacing=0 class="hfill mxw2"><caption><x></x></caption><td><t></t></td></table></div>
<div class="grid"><table cellpadding=0 cellspacing=0 class="hfill"><caption class="w6"><x></x></caption><td><t></t></td></table></div>
<div class="grid"><table cellpadding=0 cellspacing=0 class="hfill mxw2"><caption class="w6"><x></x></caption><td><t></t></td></table></div>
<div class="grid"><table cellpadding=0 cellspacing=0 class="end"><caption><x></x></caption><td><t></t></td></table></div>
<div class="grid"><table cellpadding=0 cellspacing=0 class="end mxw2"><caption><x></x></caption><td><t></t></td></table></div>
<div class="grid"><table cellpadding=0 cellspacing=0 class="hfill sa"><caption><x></x></caption><td><t></t></td></table></div>
<div class="grid"><table cellpadding=0 cellspacing=0 class="hfill sa mxw2"><caption><x></x></caption><td><t></t></td></table></div>
<div class="grid"><table cellpadding=0 cellspacing=0 class="hfill na"><caption><x></x></caption><td><t></t></td></table></div>
<div class="grid"><table cellpadding=0 cellspacing=0 class="hfill na mxw2"><caption><x></x></caption><td><t></t></td></table></div>
<div class="grid"><table cellpadding=0 cellspacing=0 class="as"><caption><x></x></caption><td><t></t></td></table></div>
<div class="grid"><table cellpadding=0 cellspacing=0 class="as mxw2"><caption><x></x></caption><td><t></t></td></table></div>
<div class="grid"><table cellpadding=0 cellspacing=0 class="an"><caption><x></x></caption><td><t></t></td></table></div>
<div class="grid"><table cellpadding=0 cellspacing=0 class="an mxw2"><caption><x></x></caption><td><t></t></td></table></div>
<div class="grid"><table cellpadding=0 cellspacing=0 class="as"><caption class="w6"><x></x></caption><td><t></t></td></table></div>
<div class="grid"><table cellpadding=0 cellspacing=0 class="as mxw2"><caption class="w6"><x></x></caption><td><t></t></td></table></div>
<div class="grid"><table cellpadding=0 cellspacing=0 class="an"><caption class="w6"><x></x></caption><td><t></t></td></table></div>
<div class="grid"><table cellpadding=0 cellspacing=0 class="an mxw2"><caption class="w6"><x></x></caption><td><t></t></td></table></div>
<pre><!--min-width:20px--></pre>
<div class="grid"><table cellpadding=0 cellspacing=0 class="hfill mw20"><caption><x></x></caption><td><t></t></td></table></div>
<div class="grid"><table cellpadding=0 cellspacing=0 class="mw20 mxh10"><caption><x></x></caption><td><t></t></td></table></div>
<div class="grid"><table cellpadding=0 cellspacing=0 class="end mw20"><caption><x></x></caption><td><t></t></td></table></div>
<div class="grid"><table cellpadding=0 cellspacing=0 class="end h8 mw20 mxh10"><caption><x></x></caption><td><t></t></td></table></div>
<div class="grid"><table cellpadding=0 cellspacing=0 class="hfill sa mw20"><caption><x></x></caption><td><t></t></td></table></div>
<div class="grid"><table cellpadding=0 cellspacing=0 class="sa mw20 mxh10"><caption><x></x></caption><td><t></t></td></table></div>
<div class="grid"><table cellpadding=0 cellspacing=0 class="hfill na mw20"><caption><x></x></caption><td><t></t></td></table></div>
<div class="grid"><table cellpadding=0 cellspacing=0 class="na mw20 mxh10"><caption><x></x></caption><td><t></t></td></table></div>
<div class="grid"><table cellpadding=0 cellspacing=0 class="as mw20"><caption><x></x></caption><td><t></t></td></table></div>
<div class="grid"><table cellpadding=0 cellspacing=0 class="as h8 mw20 mxh10"><caption><x></x></caption><td><t></t></td></table></div>
<div class="grid"><table cellpadding=0 cellspacing=0 class="an mw20"><caption><x></x></caption><td><t></t></td></table></div>
<div class="grid"><table cellpadding=0 cellspacing=0 class="an h8 mw20 mxh10"><caption><x></x></caption><td><t></t></td></table></div>
<div class="grid mw20"><table cellpadding=0 cellspacing=0 class="hfill mw20"><caption><x></x></caption><td><t></t></td></table></div>
<div class="grid mw20"><table cellpadding=0 cellspacing=0 class="mw20 mxh10"><caption><x></x></caption><td><t></t></td></table></div>
<div class="grid mw20"><table cellpadding=0 cellspacing=0 class="end mw20"><caption><x></x></caption><td><t></t></td></table></div>
<div class="grid mw20"><table cellpadding=0 cellspacing=0 class="end h8 mw20 mxh10"><caption><x></x></caption><td><t></t></td></table></div>
<div class="grid mw20"><table cellpadding=0 cellspacing=0 class="hfill sa mw20"><caption><x></x></caption><td><t></t></td></table></div>
<div class="grid mw20"><table cellpadding=0 cellspacing=0 class="sa mw20 mxh10"><caption><x></x></caption><td><t></t></td></table></div>
<div class="grid mw20"><table cellpadding=0 cellspacing=0 class="hfill na mw20"><caption><x></x></caption><td><t></t></td></table></div>
<div class="grid mw20"><table cellpadding=0 cellspacing=0 class="na mw20 mxh10"><caption><x></x></caption><td><t></t></td></table></div>
<div class="grid mw20"><table cellpadding=0 cellspacing=0 class="as mw20"><caption><x></x></caption><td><t></t></td></table></div>
<div class="grid mw20"><table cellpadding=0 cellspacing=0 class="as h8 mw20 mxh10"><caption><x></x></caption><td><t></t></td></table></div>
<div class="grid mw20"><table cellpadding=0 cellspacing=0 class="an mw20"><caption><x></x></caption><td><t></t></td></table></div>
<div class="grid mw20"><table cellpadding=0 cellspacing=0 class="an h8 mw20 mxh10"><caption><x></x></caption><td><t></t></td></table></div>
<pre><!--min-width:0--></pre>
<div class="grid"><table cellpadding=0 cellspacing=0 class="hfill mw0"><caption><x></x></caption><td><t></t></td></table></div>
<div class="grid"><table cellpadding=0 cellspacing=0 class="mw0 mxh10"><caption><x></x></caption><td><t></t></td></table></div>
<div class="grid"><table cellpadding=0 cellspacing=0 class="hfill mw0"><caption class="w6"><x></x></caption><td><t></t></td></table></div>
<div class="grid"><table cellpadding=0 cellspacing=0 class="mw0 mxh10"><caption class="w6"><x></x></caption><td><t></t></td></table></div>
<div class="grid"><table cellpadding=0 cellspacing=0 class="end mw0"><caption><x></x></caption><td><t></t></td></table></div>
<div class="grid"><table cellpadding=0 cellspacing=0 class="end h8 mw0 mxh10"><caption><x></x></caption><td><t></t></td></table></div>
<div class="grid"><table cellpadding=0 cellspacing=0 class="hfill sa mw0"><caption><x></x></caption><td><t></t></td></table></div>
<div class="grid"><table cellpadding=0 cellspacing=0 class="sa mw0 mxh10"><caption><x></x></caption><td><t></t></td></table></div>
<div class="grid"><table cellpadding=0 cellspacing=0 class="hfill na mw0"><caption><x></x></caption><td><t></t></td></table></div>
<div class="grid"><table cellpadding=0 cellspacing=0 class="na mw0 mxh10"><caption><x></x></caption><td><t></t></td></table></div>
<div class="grid"><table cellpadding=0 cellspacing=0 class="as mw0"><caption><x></x></caption><td><t></t></td></table></div>
<div class="grid"><table cellpadding=0 cellspacing=0 class="as h8 mw0 mxh10"><caption><x></x></caption><td><t></t></td></table></div>
<div class="grid"><table cellpadding=0 cellspacing=0 class="an mw0"><caption><x></x></caption><td><t></t></td></table></div>
<div class="grid"><table cellpadding=0 cellspacing=0 class="an h8 mw0 mxh10"><caption><x></x></caption><td><t></t></td></table></div>
<div class="grid"><table cellpadding=0 cellspacing=0 class="as mw0"><caption class="w6"><x></x></caption><td><t></t></td></table></div>
<div class="grid"><table cellpadding=0 cellspacing=0 class="as h8 mw0 mxh10"><caption class="w6"><x></x></caption><td><t></t></td></table></div>
<div class="grid"><table cellpadding=0 cellspacing=0 class="an mw0"><caption class="w6"><x></x></caption><td><t></t></td></table></div>
<div class="grid"><table cellpadding=0 cellspacing=0 class="an h8 mw0 mxh10"><caption class="w6"><x></x></caption><td><t></t></td></table></div>
<pre><!--width:20px--></pre>
@ -149,18 +151,18 @@ t { display:block; width:6px; height:6px; }
<pre><!--width:20px--></pre>
<div class="grid"><table cellpadding=0 cellspacing=0 class="end w20"><caption><x></x></caption><td><t></t></td></table></div>
<div class="grid"><table cellpadding=0 cellspacing=0 class="h8 end w20 mxh10"><caption><x></x></caption><td><t></t></td></table></div>
<div class="grid"><table cellpadding=0 cellspacing=0 class="end w20"><caption><x></x></caption><td><t></t></td></table></div>
<div class="grid"><table cellpadding=0 cellspacing=0 class="h8 end w20 mxh10"><caption><x></x></caption><td><t></t></td></table></div>
<div class="grid"><table cellpadding=0 cellspacing=0 class="hfill sa w20"><caption><x></x></caption><td><t></t></td></table></div>
<div class="grid"><table cellpadding=0 cellspacing=0 class="sa w20 mxh10"><caption><x></x></caption><td><t></t></td></table></div>
<div class="grid"><table cellpadding=0 cellspacing=0 class="hfill na w20"><caption><x></x></caption><td><t></t></td></table></div>
<div class="grid"><table cellpadding=0 cellspacing=0 class="na w20 mxh10"><caption><x></x></caption><td><t></t></td></table></div>
<div class="grid"><table cellpadding=0 cellspacing=0 class="as w20"><caption><x></x></caption><td><t></t></td></table></div>
<div class="grid"><table cellpadding=0 cellspacing=0 class="h8 as w20 mxh10"><caption><x></x></caption><td><t></t></td></table></div>
<div class="grid"><table cellpadding=0 cellspacing=0 class="an w20"><caption><x></x></caption><td><t></t></td></table></div>
<div class="grid"><table cellpadding=0 cellspacing=0 class="h8 an w20 mxh10"><caption><x></x></caption><td><t></t></td></table></div>
<div class="grid mw20"><table cellpadding=0 cellspacing=0 class="end w20"><caption><x></x></caption><td><t></t></td></table></div>
<div class="grid mw20"><table cellpadding=0 cellspacing=0 class="h8 end w20 mxh10"><caption><x></x></caption><td><t></t></td></table></div>
<div class="grid mw20"><table cellpadding=0 cellspacing=0 class="end w20"><caption><x></x></caption><td><t></t></td></table></div>
<div class="grid mw20"><table cellpadding=0 cellspacing=0 class="h8 end w20 mxh10"><caption><x></x></caption><td><t></t></td></table></div>
<div class="grid mw20"><table cellpadding=0 cellspacing=0 class="hfill sa w20"><caption><x></x></caption><td><t></t></td></table></div>
<div class="grid mw20"><table cellpadding=0 cellspacing=0 class="sa w20 mxh10"><caption><x></x></caption><td><t></t></td></table></div>
<div class="grid mw20"><table cellpadding=0 cellspacing=0 class="hfill na w20"><caption><x></x></caption><td><t></t></td></table></div>
<div class="grid mw20"><table cellpadding=0 cellspacing=0 class="na w20 mxh10"><caption><x></x></caption><td><t></t></td></table></div>
<div class="grid mw20"><table cellpadding=0 cellspacing=0 class="as w20"><caption><x></x></caption><td><t></t></td></table></div>
<div class="grid mw20"><table cellpadding=0 cellspacing=0 class="h8 as w20 mxh10"><caption><x></x></caption><td><t></t></td></table></div>
<div class="grid mw20"><table cellpadding=0 cellspacing=0 class="an w20"><caption><x></x></caption><td><t></t></td></table></div>
<div class="grid mw20"><table cellpadding=0 cellspacing=0 class="h8 an w20 mxh10"><caption><x></x></caption><td><t></t></td></table></div>
<pre><!--height:20px--></pre>
@ -175,18 +177,18 @@ t { display:block; width:6px; height:6px; }
<pre><!--height:20px--></pre>
<div class="grid"><table cellpadding=0 cellspacing=0 class="h20"><caption><x></x></caption><td><t></t></td></table></div>
<div class="grid"><table cellpadding=0 cellspacing=0 class="h20 mxw2"><caption><x></x></caption><td><t></t></td></table></div>
<div class="grid"><table cellpadding=0 cellspacing=0 class="h20"><caption class="w6"><x></x></caption><td><t></t></td></table></div>
<div class="grid"><table cellpadding=0 cellspacing=0 class="h20 mxw2"><caption class="w6"><x></x></caption><td><t></t></td></table></div>
<div class="grid"><table cellpadding=0 cellspacing=0 class="end h20"><caption><x></x></caption><td><t></t></td></table></div>
<div class="grid"><table cellpadding=0 cellspacing=0 class="w8 end h20 mxw10"><caption><x></x></caption><td><t></t></td></table></div>
<div class="grid"><table cellpadding=0 cellspacing=0 class="sa h20"><caption><x></x></caption><td><t></t></td></table></div>
<div class="grid"><table cellpadding=0 cellspacing=0 class="sa h20 mxw2"><caption><x></x></caption><td><t></t></td></table></div>
<div class="grid"><table cellpadding=0 cellspacing=0 class="na h20"><caption><x></x></caption><td><t></t></td></table></div>
<div class="grid"><table cellpadding=0 cellspacing=0 class="w8 na h20 mxw10"><caption><x></x></caption><td><t></t></td></table></div>
<div class="grid"><table cellpadding=0 cellspacing=0 class="as h20"><caption><x></x></caption><td><t></t></td></table></div>
<div class="grid"><table cellpadding=0 cellspacing=0 class="as h20 mxw2"><caption><x></x></caption><td><t></t></td></table></div>
<div class="grid"><table cellpadding=0 cellspacing=0 class="an h20"><caption><x></x></caption><td><t></t></td></table></div>
<div class="grid"><table cellpadding=0 cellspacing=0 class="w8 an h20 mxw10"><caption><x></x></caption><td><t></t></td></table></div>
<div class="grid"><table cellpadding=0 cellspacing=0 class="as h20"><caption class="w6"><x></x></caption><td><t></t></td></table></div>
<div class="grid"><table cellpadding=0 cellspacing=0 class="as h20 mxw2"><caption class="w6"><x></x></caption><td><t></t></td></table></div>
<div class="grid"><table cellpadding=0 cellspacing=0 class="an h20"><caption class="w6"><x></x></caption><td><t></t></td></table></div>
<div class="grid"><table cellpadding=0 cellspacing=0 class="w8 an h20 mxw10"><caption class="w6"><x></x></caption><td><t></t></td></table></div>
</body>
</html>

View File

@ -14,10 +14,10 @@
.grid {
display: inline-grid;
border: 3px solid grey;
grid: 32px / 4px;
grid: minmax(auto,32px) / minmax(auto,4px);
margin-right:20px;
}
.r { grid: 4px / 32px; }
.r { grid: minmax(auto,4px) / minmax(auto,32px); }
table {
border: 1px solid;

View File

@ -64,11 +64,12 @@ y {
.w8 .c2 { grid-template-columns: 50px 0 minmax(100px, 1fr); }
.w8 .c3 { grid-template-columns: 56px 56px minmax(0, 1fr); }
.w8 .c4 { grid-template-columns: 0px 100px minmax(100px, 1fr); }
.w8 .c5 { grid-template-columns: 0px 40px 100px; }
.w9 .c1 { grid-template-columns: 50px minmax(100px, 1fr); }
.w9 .c2 { grid-template-columns: 50px 0 minmax(100px, 1fr); }
.w9 .c3 { grid-template-columns: 32px 32px minmax(0, 1fr); }
.w9 .c4 { grid-template-columns: 0px 100px minmax(100px, 1fr); }
.w9 .c4 { grid-template-columns: 0px 100px 100px; }
.wA .c1 { grid-template-columns: 50px minmax(100px, 1fr); }
.wA .c2 { grid-template-columns: 50px 0 minmax(100px, 1fr); }
@ -146,7 +147,7 @@ y {
<div class="grid c2"><span><a></a><a></a><a></a><a></a></span><y></y></div>
<div class="grid c3"><span><a></a><a></a><a></a><a></a></span><y></y></div>
<div class="grid c4"><span><a></a><a></a><a></a><a></a></span><y></y></div>
<div class="grid c5"><span><a></a><a></a><a></a><a></a></span><y></y></div>
<div class="grid c5"><span style="width:50px"><a></a><a></a><a></a><a></a></span><y></y></div>
</div>
<div class="w9" style="width:82px">
@ -154,7 +155,7 @@ y {
<div class="grid c2"><span><a></a><a></a><a></a><a></a></span><y></y></div>
<div class="grid c3"><span><a></a><a></a><a></a><a></a></span><y></y></div>
<div class="grid c4"><span><a></a><a></a><a></a><a></a></span><y></y></div>
<div class="grid c5"><span><a></a><a></a><a></a><a></a></span><y></y></div>
<div class="grid c5"><span style="width:50px"><a></a><a></a><a></a><a></a></span><y></y></div>
</div>
<div class="wA" style="width:22px">
@ -162,7 +163,7 @@ y {
<div class="grid c2"><span><a></a><a></a><a></a><a></a></span><y></y></div>
<div class="grid c3"><span><a></a><a></a><a></a><a></a></span><y></y></div>
<div class="grid c4"><span><a></a><a></a><a></a><a></a></span><y></y></div>
<div class="grid c5"><span><a></a><a></a><a></a><a></a></span><y></y></div>
<div class="grid c5"><span style="width:50px"><a></a><a></a><a></a><a></a></span><y></y></div>
<div class="grid c6"><span><a></a><a></a><a></a><a></a></span><y></y></div>
</div>
@ -171,7 +172,7 @@ y {
<div class="grid c2"><span><a></a><a></a><a></a><a></a></span><y></y></div>
<div class="grid c3"><span><a></a><a></a><a></a><a></a></span><y></y></div>
<div class="grid c4"><span><a></a><a></a><a></a><a></a></span><y></y></div>
<div class="grid c5"><span><a></a><a></a><a></a><a></a></span><y></y></div>
<div class="grid c5"><span style="width:50px"><a></a><a></a><a></a><a></a></span><y></y></div>
</div>
</body>

View File

@ -112,9 +112,9 @@ skip-if(Android) == grid-auto-min-sizing-percent-001.html grid-auto-min-sizing-p
== grid-item-auto-min-size-clamp-001.html grid-item-auto-min-size-clamp-001-ref.html
== grid-item-auto-min-size-clamp-002.html grid-item-auto-min-size-clamp-002-ref.html
== grid-item-auto-min-size-clamp-003.html grid-item-auto-min-size-clamp-003-ref.html
== grid-item-auto-min-size-clamp-004.html grid-item-auto-min-size-clamp-004-ref.html
# == grid-item-auto-min-size-clamp-004.html grid-item-auto-min-size-clamp-004-ref.html # bug 1421976
== grid-item-auto-min-size-clamp-005.html grid-item-auto-min-size-clamp-005-ref.html
== grid-item-auto-min-size-clamp-006.html grid-item-auto-min-size-clamp-006-ref.html
# == grid-item-auto-min-size-clamp-006.html grid-item-auto-min-size-clamp-006-ref.html # bug 1421976
== grid-item-auto-min-size-clamp-007.html grid-item-auto-min-size-clamp-007-ref.html
== grid-item-overflow-stretch-001.html grid-item-overflow-stretch-001-ref.html
== grid-item-overflow-stretch-002.html grid-item-overflow-stretch-002-ref.html

View File

@ -313,7 +313,7 @@ nsMenuBarListener::KeyPress(nsIDOMEvent* aKeyEvent)
if (mMenuBarFrame->IsActive()) {
#ifdef MOZ_WIDGET_GTK
// In GTK, this also opens the first menu.
mMenuBarFrame->GetCurrentMenuItem()->OpenMenu(true);
mMenuBarFrame->GetCurrentMenuItem()->OpenMenu(false);
#endif
aKeyEvent->StopPropagation();
aKeyEvent->PreventDefault();

View File

@ -2193,6 +2193,21 @@ nsXULPopupManager::HandleKeyboardNavigation(uint32_t aKeyCode)
aKeyCode <= nsIDOMKeyEvent::DOM_VK_DOWN, "Illegal key code");
theDirection = NS_DIRECTION_FROM_KEY_CODE(itemFrame, aKeyCode);
bool selectFirstItem = true;
#ifdef MOZ_WIDGET_GTK
nsMenuFrame* currentItem = nullptr;
if (item && mActiveMenuBar && NS_DIRECTION_IS_INLINE(theDirection)) {
currentItem = item->Frame()->GetCurrentMenuItem();
// If nothing is selected in the menu and we have a menubar, let it
// handle the movement not to steal focus from it.
if (!currentItem) {
item = nullptr;
}
}
// On menu change, only select first item if an item is already selected.
selectFirstItem = currentItem != nullptr;
#endif
// if a popup is open, first check for navigation within the popup
if (item && HandleKeyboardNavigationInPopup(item, theDirection))
return true;
@ -2205,7 +2220,7 @@ nsXULPopupManager::HandleKeyboardNavigation(uint32_t aKeyCode)
nsMenuFrame* nextItem = (theDirection == eNavigationDirection_End) ?
GetNextMenuItem(mActiveMenuBar, currentMenu, false, true) :
GetPreviousMenuItem(mActiveMenuBar, currentMenu, false, true);
mActiveMenuBar->ChangeMenuItem(nextItem, true, true);
mActiveMenuBar->ChangeMenuItem(nextItem, selectFirstItem, true);
return true;
}
else if (NS_DIRECTION_IS_BLOCK(theDirection)) {

View File

@ -128,7 +128,11 @@ MOZ_END_EXTERN_C
/*
* Suppress build warning spam (bug 578546).
*/
#if _MSC_VER < 1912
#define MOZALLOC_THROW_IF_HAS_EXCEPTIONS
#else
#define MOZALLOC_THROW_IF_HAS_EXCEPTIONS throw()
#endif
#define MOZALLOC_THROW_BAD_ALLOC_IF_HAS_EXCEPTIONS
#elif __cplusplus >= 201103
/*

View File

@ -2205,16 +2205,25 @@ pref("network.auth.private-browsing-sso", false);
// Control how throttling of http responses works - number of ms that each
// suspend and resume period lasts (prefs named appropriately)
pref("network.http.throttle.enable", true);
pref("network.http.throttle.version", 1);
// V1 prefs
pref("network.http.throttle.suspend-for", 900);
pref("network.http.throttle.resume-for", 100);
// V2 prefs
pref("network.http.throttle.read-limit-bytes", 8000);
pref("network.http.throttle.read-interval-ms", 500);
// Common prefs
// Delay we resume throttled background responses after the last unthrottled
// response has finished. Prevents resuming too soon during an active page load
// at which sub-resource reqeusts quickly come and go.
pref("network.http.throttle.resume-background-in", 1000);
pref("network.http.throttle.hold-time-ms", 800);
// After the last transaction activation or last data chunk response we only
// throttle for this period of time. This prevents comet and unresponsive
// http requests to engage long-standing throttling.
pref("network.http.throttle.time-window", 3000);
pref("network.http.throttle.max-time-ms", 500);
// Give higher priority to requests resulting from a user interaction event
// like click-to-play, image fancy-box zoom, navigation.

View File

@ -116,10 +116,13 @@ nsHttpConnectionMgr::nsHttpConnectionMgr()
, mMaxPersistConnsPerProxy(0)
, mMaxRequestDelay(0)
, mThrottleEnabled(false)
, mThrottleVersion(2)
, mThrottleSuspendFor(0)
, mThrottleResumeFor(0)
, mThrottleResumeIn(0)
, mThrottleTimeWindow(0)
, mThrottleReadLimit(0)
, mThrottleReadInterval(0)
, mThrottleHoldTime(0)
, mThrottleMaxTime(0)
, mIsShuttingDown(false)
, mNumActiveConns(0)
, mNumIdleConns(0)
@ -174,10 +177,13 @@ nsHttpConnectionMgr::Init(uint16_t maxUrgentExcessiveConns,
uint16_t maxPersistConnsPerProxy,
uint16_t maxRequestDelay,
bool throttleEnabled,
uint32_t throttleVersion,
uint32_t throttleSuspendFor,
uint32_t throttleResumeFor,
uint32_t throttleResumeIn,
uint32_t throttleTimeWindow)
uint32_t throttleReadLimit,
uint32_t throttleReadInterval,
uint32_t throttleHoldTime,
uint32_t throttleMaxTime)
{
LOG(("nsHttpConnectionMgr::Init\n"));
@ -191,10 +197,13 @@ nsHttpConnectionMgr::Init(uint16_t maxUrgentExcessiveConns,
mMaxRequestDelay = maxRequestDelay;
mThrottleEnabled = throttleEnabled;
mThrottleVersion = throttleVersion;
mThrottleSuspendFor = throttleSuspendFor;
mThrottleResumeFor = throttleResumeFor;
mThrottleResumeIn = throttleResumeIn;
mThrottleTimeWindow = TimeDuration::FromMilliseconds(throttleTimeWindow);
mThrottleReadLimit = throttleReadLimit;
mThrottleReadInterval = throttleReadInterval;
mThrottleHoldTime = throttleHoldTime;
mThrottleMaxTime = TimeDuration::FromMilliseconds(throttleMaxTime);
mIsShuttingDown = false;
}
@ -2832,11 +2841,17 @@ nsHttpConnectionMgr::OnMsgUpdateParam(int32_t inParam, ARefBase *)
case THROTTLING_RESUME_FOR:
mThrottleResumeFor = value;
break;
case THROTTLING_RESUME_IN:
mThrottleResumeIn = value;
case THROTTLING_READ_LIMIT:
mThrottleReadLimit = value;
break;
case THROTTLING_TIME_WINDOW:
mThrottleTimeWindow = TimeDuration::FromMilliseconds(value);
case THROTTLING_READ_INTERVAL:
mThrottleReadInterval = value;
break;
case THROTTLING_HOLD_TIME:
mThrottleHoldTime = value;
break;
case THROTTLING_MAX_TIME:
mThrottleMaxTime = TimeDuration::FromMilliseconds(value);
break;
default:
NS_NOTREACHED("unexpected parameter name");
@ -2952,7 +2967,7 @@ void nsHttpConnectionMgr::TouchThrottlingTimeWindow(bool aEnsureTicker)
MOZ_ASSERT(OnSocketThread(), "not on socket thread");
mThrottlingWindowEndsAt = TimeStamp::NowLoRes() + mThrottleTimeWindow;
mThrottlingWindowEndsAt = TimeStamp::NowLoRes() + mThrottleMaxTime;
if (!mThrottleTicker &&
MOZ_LIKELY(aEnsureTicker) && MOZ_LIKELY(mThrottleEnabled)) {
@ -3091,11 +3106,13 @@ nsHttpConnectionMgr::RemoveActiveTransaction(nsHttpTransaction * aTrans,
return;
}
if (!mThrottlingInhibitsReading) {
// There is then nothing to wake up. Affected transactions will not be put
// to sleep automatically on next tick.
LOG((" reading not currently inhibited"));
return;
if (mThrottleVersion == 1) {
if (!mThrottlingInhibitsReading) {
// There is then nothing to wake up. Affected transactions will not be put
// to sleep automatically on next tick.
LOG((" reading not currently inhibited"));
return;
}
}
if (mActiveTabUnthrottledTransactionsExist) {
@ -3140,22 +3157,36 @@ nsHttpConnectionMgr::UpdateActiveTransaction(nsHttpTransaction * aTrans)
{
LOG(("nsHttpConnectionMgr::UpdateActiveTransaction ENTER t=%p", aTrans));
AddActiveTransaction(aTrans);
// First remove then add. In case of a download that is the only active
// transaction and has just been marked as download (goes unthrottled to
// throttled), adding first would cause it to be throttled for first few
// milliseconds - becuause it would appear as if there were both throttled
// and unthrottled transactions at the time.
Maybe<bool> reversed;
reversed.emplace(!aTrans->EligibleForThrottling());
RemoveActiveTransaction(aTrans, reversed);
AddActiveTransaction(aTrans);
LOG(("nsHttpConnectionMgr::UpdateActiveTransaction EXIT t=%p", aTrans));
}
bool
nsHttpConnectionMgr::ShouldStopReading(nsHttpTransaction * aTrans)
nsHttpConnectionMgr::ShouldThrottle(nsHttpTransaction * aTrans)
{
MOZ_ASSERT(OnSocketThread(), "not on socket thread");
if (!mThrottlingInhibitsReading || !mThrottleEnabled) {
return false;
LOG(("nsHttpConnectionMgr::ShouldThrottle trans=%p", aTrans));
if (mThrottleVersion == 1) {
if (!mThrottlingInhibitsReading || !mThrottleEnabled) {
return false;
}
} else {
if (!mThrottleEnabled) {
return false;
}
}
uint64_t tabId = aTrans->TopLevelOuterContentWindowId();
@ -3168,54 +3199,66 @@ nsHttpConnectionMgr::ShouldStopReading(nsHttpTransaction * aTrans)
// Chrome initiated and unidentified transactions just respect
// their throttle flag, when something for the active tab is happening.
// This also includes downloads.
LOG((" active tab loads, trans is tab-less, throttled=%d", throttled));
return throttled;
}
if (!forActiveTab) {
// This is a background tab request, we want them to always throttle
// when there are transactions running for the ative tab.
LOG((" active tab loads, trans not of the active tab"));
return true;
}
if (mActiveTabUnthrottledTransactionsExist) {
// Unthrottled transactions for the active tab take precedence
LOG((" active tab loads unthrottled, trans throttled=%d", throttled));
return throttled;
}
LOG((" trans for active tab, don't throttle"));
return false;
}
MOZ_ASSERT(!forActiveTab);
if (mDelayedResumeReadTimer) {
// If this timer exists, background transactions are scheduled to be woken
// after a delay, hence leave them asleep.
return true;
}
if (!mActiveTransactions[false].IsEmpty()) {
// This means there are unthrottled active transactions for background tabs.
// If we are here, there can't be any transactions for the active tab.
// (If there is no transaction for a tab id, there is no entry for it in
// the hashtable.)
LOG((" backround tab(s) load unthrottled, trans throttled=%d", throttled));
return throttled;
}
// There are only unthrottled transactions for background tabs: don't throttle.
LOG((" backround tab(s) load throttled, don't throttle"));
return false;
}();
if (forActiveTab && !stop) {
// This active-tab transaction is allowed to read even though
// we are in the middle of "stop reading" interval. Hence,
// This is an active-tab transaction and is allowed to read. Hence,
// prolong the throttle time window to make sure all 'lower-decks'
// transactions will actually throttle.
TouchThrottlingTimeWindow();
return false;
}
// Only stop reading when in the 3 seconds throttle time window.
// This window is prolonged (restarted) by a call to TouchThrottlingTimeWindow.
return stop && InThrottlingTimeWindow();
// Only stop reading when in the configured throttle max-time (aka time window).
// This window is prolonged (restarted) by a call to TouchThrottlingTimeWindow
// called on new transaction activation or on receive of response bytes of an
// active tab transaction.
bool inWindow = InThrottlingTimeWindow();
LOG((" stop=%d, in-window=%d, delayed-bck-timer=%d",
stop, inWindow, !!mDelayedResumeReadTimer));
if (!forActiveTab) {
// If the delayed background resume timer exists, background transactions are
// scheduled to be woken after a delay, hence leave them throttled.
inWindow = inWindow || mDelayedResumeReadTimer;
}
return stop && inWindow;
}
bool nsHttpConnectionMgr::IsConnEntryUnderPressure(nsHttpConnectionInfo *connInfo)
@ -3276,12 +3319,16 @@ nsHttpConnectionMgr::EnsureThrottleTickerIfNeeded()
return;
}
MOZ_ASSERT(!mThrottlingInhibitsReading);
mThrottleTicker = NS_NewTimer();
if (mThrottleTicker) {
mThrottleTicker->Init(this, mThrottleSuspendFor, nsITimer::TYPE_ONE_SHOT);
mThrottlingInhibitsReading = true;
if (mThrottleVersion == 1) {
MOZ_ASSERT(!mThrottlingInhibitsReading);
mThrottleTicker->Init(this, mThrottleSuspendFor, nsITimer::TYPE_ONE_SHOT);
mThrottlingInhibitsReading = true;
} else {
mThrottleTicker->Init(this, mThrottleReadInterval, nsITimer::TYPE_ONE_SHOT);
}
}
LogActiveTransactions('^');
@ -3304,7 +3351,10 @@ nsHttpConnectionMgr::DestroyThrottleTicker()
LOG(("nsHttpConnectionMgr::DestroyThrottleTicker"));
mThrottleTicker->Cancel();
mThrottleTicker = nullptr;
mThrottlingInhibitsReading = false;
if (mThrottleVersion == 1) {
mThrottlingInhibitsReading = false;
}
LogActiveTransactions('v');
}
@ -3314,27 +3364,46 @@ nsHttpConnectionMgr::ThrottlerTick()
{
MOZ_ASSERT(OnSocketThread(), "not on socket thread");
mThrottlingInhibitsReading = !mThrottlingInhibitsReading;
if (mThrottleVersion == 1) {
mThrottlingInhibitsReading = !mThrottlingInhibitsReading;
LOG(("nsHttpConnectionMgr::ThrottlerTick inhibit=%d", mThrottlingInhibitsReading));
LOG(("nsHttpConnectionMgr::ThrottlerTick inhibit=%d", mThrottlingInhibitsReading));
// If there are only background transactions to be woken after a delay, keep
// the ticker so that we woke them only for the resume-for interval and then
// throttle them again until the background-resume delay passes.
if (!mThrottlingInhibitsReading &&
!mDelayedResumeReadTimer &&
(!IsThrottleTickerNeeded() || !InThrottlingTimeWindow())) {
LOG((" last tick"));
mThrottleTicker = nullptr;
}
// If there are only background transactions to be woken after a delay, keep
// the ticker so that we woke them only for the resume-for interval and then
// throttle them again until the background-resume delay passes.
if (!mThrottlingInhibitsReading &&
!mDelayedResumeReadTimer &&
(!IsThrottleTickerNeeded() || !InThrottlingTimeWindow())) {
LOG((" last tick"));
mThrottleTicker = nullptr;
}
if (mThrottlingInhibitsReading) {
if (mThrottleTicker) {
mThrottleTicker->Init(this, mThrottleSuspendFor, nsITimer::TYPE_ONE_SHOT);
if (mThrottlingInhibitsReading) {
if (mThrottleTicker) {
mThrottleTicker->Init(this, mThrottleSuspendFor, nsITimer::TYPE_ONE_SHOT);
}
} else {
if (mThrottleTicker) {
mThrottleTicker->Init(this, mThrottleResumeFor, nsITimer::TYPE_ONE_SHOT);
}
ResumeReadOf(mActiveTransactions[false], true);
ResumeReadOf(mActiveTransactions[true]);
}
} else {
LOG(("nsHttpConnectionMgr::ThrottlerTick"));
// If there are only background transactions to be woken after a delay, keep
// the ticker so that we still keep the low read limit for that time.
if (!mDelayedResumeReadTimer &&
(!IsThrottleTickerNeeded() || !InThrottlingTimeWindow())) {
LOG((" last tick"));
mThrottleTicker = nullptr;
}
if (mThrottleTicker) {
mThrottleTicker->Init(this, mThrottleResumeFor, nsITimer::TYPE_ONE_SHOT);
mThrottleTicker->Init(this, mThrottleReadInterval, nsITimer::TYPE_ONE_SHOT);
}
ResumeReadOf(mActiveTransactions[false], true);
@ -3345,13 +3414,25 @@ nsHttpConnectionMgr::ThrottlerTick()
void
nsHttpConnectionMgr::DelayedResumeBackgroundThrottledTransactions()
{
if (mDelayedResumeReadTimer) {
return;
MOZ_ASSERT(OnSocketThread(), "not on socket thread");
if (mThrottleVersion == 1) {
if (mDelayedResumeReadTimer) {
return;
}
} else {
// If the mThrottleTicker doesn't exist, there is nothing currently
// being throttled. Hence, don't invoke the hold time interval.
// This is called also when a single download transaction becomes
// marked as throttleable. We would otherwise block it unnecessarily.
if (mDelayedResumeReadTimer || !mThrottleTicker) {
return;
}
}
LOG(("nsHttpConnectionMgr::DelayedResumeBackgroundThrottledTransactions"));
NS_NewTimerWithObserver(getter_AddRefs(mDelayedResumeReadTimer),
this, mThrottleResumeIn, nsITimer::TYPE_ONE_SHOT);
this, mThrottleHoldTime, nsITimer::TYPE_ONE_SHOT);
}
void
@ -3464,7 +3545,6 @@ nsHttpConnectionMgr::OnMsgUpdateCurrentTopLevelOuterContentWindowId(
}
bool activeTabWasLoading = mActiveTabTransactionsExist;
bool activeTabIdChanged = mCurrentTopLevelOuterContentWindowId != winId;
uint64_t previousWindowId = mCurrentTopLevelOuterContentWindowId;
mCurrentTopLevelOuterContentWindowId = winId;
@ -3479,17 +3559,15 @@ nsHttpConnectionMgr::OnMsgUpdateCurrentTopLevelOuterContentWindowId(
nsTArray<RefPtr<nsHttpTransaction>> *transactions = nullptr;
if (activeTabIdChanged) {
// Update the "Exists" caches and resume any transactions that now deserve it,
// changing the active tab changes the conditions for throttling.
transactions = mActiveTransactions[false].Get(mCurrentTopLevelOuterContentWindowId);
mActiveTabUnthrottledTransactionsExist = !!transactions;
// Update the "Exists" caches and resume any transactions that now deserve it,
// changing the active tab changes the conditions for throttling.
transactions = mActiveTransactions[false].Get(mCurrentTopLevelOuterContentWindowId);
mActiveTabUnthrottledTransactionsExist = !!transactions;
if (!mActiveTabUnthrottledTransactionsExist) {
transactions = mActiveTransactions[true].Get(mCurrentTopLevelOuterContentWindowId);
}
mActiveTabTransactionsExist = !!transactions;
if (!mActiveTabUnthrottledTransactionsExist) {
transactions = mActiveTransactions[true].Get(mCurrentTopLevelOuterContentWindowId);
}
mActiveTabTransactionsExist = !!transactions;
if (transactions) {
// This means there are some transactions for this newly activated tab, resume them
@ -3513,8 +3591,8 @@ nsHttpConnectionMgr::OnMsgUpdateCurrentTopLevelOuterContentWindowId(
}
if (!mActiveTransactions[true].IsEmpty()) {
LOG((" delayed resuming throttled background transactions"));
DelayedResumeBackgroundThrottledTransactions();
LOG((" resuming throttled background transactions"));
ResumeReadOf(mActiveTransactions[true]);
return;
}

View File

@ -60,8 +60,10 @@ public:
THROTTLING_ENABLED,
THROTTLING_SUSPEND_FOR,
THROTTLING_RESUME_FOR,
THROTTLING_RESUME_IN,
THROTTLING_TIME_WINDOW
THROTTLING_READ_LIMIT,
THROTTLING_READ_INTERVAL,
THROTTLING_HOLD_TIME,
THROTTLING_MAX_TIME
};
//-------------------------------------------------------------------------
@ -76,10 +78,13 @@ public:
uint16_t maxPersistentConnectionsPerProxy,
uint16_t maxRequestDelay,
bool throttleEnabled,
uint32_t throttleVersion,
uint32_t throttleSuspendFor,
uint32_t throttleResumeFor,
uint32_t throttleResumeIn,
uint32_t throttleTimeWindow);
uint32_t throttleReadLimit,
uint32_t throttleReadInterval,
uint32_t throttleHoldTime,
uint32_t throttleMaxTime);
MOZ_MUST_USE nsresult Shutdown();
//-------------------------------------------------------------------------
@ -225,19 +230,19 @@ public:
void UpdateActiveTransaction(nsHttpTransaction* aTrans);
// called by nsHttpTransaction::WriteSegments. decides whether the transaction
// should stop reading data based on: the throttling ticker status, overall
// status of all active transactions regarding active tab and respective
// throttling state.
bool ShouldStopReading(nsHttpTransaction* aTrans);
// should limit reading its reponse data. There are various conditions this
// methods evaluates. If called by an active-tab non-throttled transaction,
// the throttling window time will be prolonged.
bool ShouldThrottle(nsHttpTransaction* aTrans);
// prolongs the throttling time window to now + the window preferred size
// prolongs the throttling time window to now + the window preferred delay.
// called when:
// - any transaction is activated
// - or when a currently unthrottled transaction for the active window receives data
void TouchThrottlingTimeWindow(bool aEnsureTicker = true);
// return true iff the connection has pending transactions for the active tab.
// it's mainly used to disallow throttling (stop reading) of a response
// it's mainly used to disallow throttling (limit reading) of a response
// belonging to the same conn info to free up a connection ASAP.
// NOTE: relatively expensive to call, there are two hashtable lookups.
bool IsConnEntryUnderPressure(nsHttpConnectionInfo*);
@ -531,10 +536,13 @@ private:
uint16_t mMaxPersistConnsPerProxy;
uint16_t mMaxRequestDelay; // in seconds
bool mThrottleEnabled;
uint32_t mThrottleVersion;
uint32_t mThrottleSuspendFor;
uint32_t mThrottleResumeFor;
uint32_t mThrottleResumeIn;
TimeDuration mThrottleTimeWindow;
uint32_t mThrottleReadLimit;
uint32_t mThrottleReadInterval;
uint32_t mThrottleHoldTime;
TimeDuration mThrottleMaxTime;
Atomic<bool, mozilla::Relaxed> mIsShuttingDown;
//-------------------------------------------------------------------------
@ -717,6 +725,7 @@ private:
// mActiveTransactions[0] are all unthrottled transactions, mActiveTransactions[1] throttled.
nsClassHashtable<nsUint64HashKey, nsTArray<RefPtr<nsHttpTransaction>>> mActiveTransactions[2];
// V1 specific
// Whether we are inside the "stop reading" interval, altered by the throttle ticker
bool mThrottlingInhibitsReading;
@ -729,10 +738,17 @@ private:
// The method also unschedules the delayed resume of background tabs timer
// if the ticker was about to be scheduled.
void EnsureThrottleTickerIfNeeded();
// V1:
// Drops also the mThrottlingInhibitsReading flag. Immediate or delayed resume
// of currently throttled transactions is not affected by this method.
// V2:
// Immediate or delayed resume of currently throttled transactions is not
// affected by this method.
void DestroyThrottleTicker();
// V1:
// Handler for the ticker: alters the mThrottlingInhibitsReading flag.
// V2:
// Handler for the ticker: calls ResumeReading() for all throttled transactions.
void ThrottlerTick();
// mechanism to delay immediate resume of background tabs and chrome initiated

View File

@ -211,10 +211,13 @@ nsHttpHandler::nsHttpHandler()
, mMaxPersistentConnectionsPerServer(2)
, mMaxPersistentConnectionsPerProxy(4)
, mThrottleEnabled(true)
, mThrottleVersion(2)
, mThrottleSuspendFor(3000)
, mThrottleResumeFor(200)
, mThrottleResumeIn(400)
, mThrottleTimeWindow(3000)
, mThrottleReadLimit(8000)
, mThrottleReadInterval(500)
, mThrottleHoldTime(600)
, mThrottleMaxTime(3000)
, mUrgentStartEnabled(true)
, mTailBlockingEnabled(true)
, mTailDelayQuantum(600)
@ -613,10 +616,13 @@ nsHttpHandler::InitConnectionMgr()
mMaxPersistentConnectionsPerProxy,
mMaxRequestDelay,
mThrottleEnabled,
mThrottleVersion,
mThrottleSuspendFor,
mThrottleResumeFor,
mThrottleResumeIn,
mThrottleTimeWindow);
mThrottleReadLimit,
mThrottleReadInterval,
mThrottleHoldTime,
mThrottleMaxTime);
return rv;
}
@ -1639,6 +1645,11 @@ nsHttpHandler::PrefsChanged(nsIPrefBranch *prefs, const char *pref)
}
}
if (PREF_CHANGED(HTTP_PREF("throttle.version"))) {
rv = prefs->GetIntPref(HTTP_PREF("throttle.version"), &val);
mThrottleVersion = (uint32_t)clamped(val, 1, 2);
}
if (PREF_CHANGED(HTTP_PREF("throttle.suspend-for"))) {
rv = prefs->GetIntPref(HTTP_PREF("throttle.suspend-for"), &val);
mThrottleSuspendFor = (uint32_t)clamped(val, 0, 120000);
@ -1657,21 +1668,39 @@ nsHttpHandler::PrefsChanged(nsIPrefBranch *prefs, const char *pref)
}
}
if (PREF_CHANGED(HTTP_PREF("throttle.resume-background-in"))) {
rv = prefs->GetIntPref(HTTP_PREF("throttle.resume-background-in"), &val);
mThrottleResumeIn = (uint32_t)clamped(val, 0, 120000);
if (PREF_CHANGED(HTTP_PREF("throttle.read-limit-bytes"))) {
rv = prefs->GetIntPref(HTTP_PREF("throttle.read-limit-bytes"), &val);
mThrottleReadLimit = (uint32_t)clamped(val, 0, 500000);
if (NS_SUCCEEDED(rv) && mConnMgr) {
Unused << mConnMgr->UpdateParam(nsHttpConnectionMgr::THROTTLING_RESUME_IN,
mThrottleResumeIn);
Unused << mConnMgr->UpdateParam(nsHttpConnectionMgr::THROTTLING_READ_LIMIT,
mThrottleReadLimit);
}
}
if (PREF_CHANGED(HTTP_PREF("throttle.time-window"))) {
rv = prefs->GetIntPref(HTTP_PREF("throttle.time-window"), &val);
mThrottleTimeWindow = (uint32_t)clamped(val, 0, 120000);
if (PREF_CHANGED(HTTP_PREF("throttle.read-interval-ms"))) {
rv = prefs->GetIntPref(HTTP_PREF("throttle.read-interval-ms"), &val);
mThrottleReadInterval = (uint32_t)clamped(val, 0, 120000);
if (NS_SUCCEEDED(rv) && mConnMgr) {
Unused << mConnMgr->UpdateParam(nsHttpConnectionMgr::THROTTLING_READ_INTERVAL,
mThrottleReadInterval);
}
}
if (PREF_CHANGED(HTTP_PREF("throttle.hold-time-ms"))) {
rv = prefs->GetIntPref(HTTP_PREF("throttle.hold-time-ms"), &val);
mThrottleHoldTime = (uint32_t)clamped(val, 0, 120000);
if (NS_SUCCEEDED(rv) && mConnMgr) {
Unused << mConnMgr->UpdateParam(nsHttpConnectionMgr::THROTTLING_HOLD_TIME,
mThrottleHoldTime);
}
}
if (PREF_CHANGED(HTTP_PREF("throttle.max-time-ms"))) {
rv = prefs->GetIntPref(HTTP_PREF("throttle.max-time-ms"), &val);
mThrottleMaxTime = (uint32_t)clamped(val, 0, 120000);
if (NS_SUCCEEDED(rv) && mConnMgr) {
Unused << mConnMgr->UpdateParam(nsHttpConnectionMgr::THROTTLING_TIME_WINDOW,
mThrottleTimeWindow);
Unused << mConnMgr->UpdateParam(nsHttpConnectionMgr::THROTTLING_MAX_TIME,
mThrottleMaxTime);
}
}

View File

@ -145,6 +145,8 @@ public:
}
uint32_t TailBlockingDelayMax() { return mTailDelayMax; }
uint32_t ThrottlingReadLimit() { return mThrottleVersion == 1 ? 0 : mThrottleReadLimit; }
// TCP Keepalive configuration values.
// Returns true if TCP keepalive should be enabled for short-lived conns.
@ -484,10 +486,13 @@ private:
uint8_t mMaxPersistentConnectionsPerProxy;
bool mThrottleEnabled;
uint32_t mThrottleVersion;
uint32_t mThrottleSuspendFor;
uint32_t mThrottleResumeFor;
uint32_t mThrottleResumeIn;
uint32_t mThrottleTimeWindow;
uint32_t mThrottleReadLimit;
uint32_t mThrottleReadInterval;
uint32_t mThrottleHoldTime;
uint32_t mThrottleMaxTime;
bool mUrgentStartEnabled;
bool mTailBlockingEnabled;

Some files were not shown because too many files have changed in this diff Show More