зеркало из https://github.com/mozilla/gecko-dev.git
merge mozilla-inbound to mozilla-central a=merge
This commit is contained in:
Коммит
7256146318
|
@ -5080,6 +5080,7 @@ nsBrowserAccess.prototype = {
|
|||
fromExternal: aIsExternal,
|
||||
inBackground: loadInBackground,
|
||||
forceNotRemote: aForceNotRemote,
|
||||
forceBrowserInsertion: true,
|
||||
opener: aOpener,
|
||||
});
|
||||
let browser = win.gBrowser.getBrowserForTab(tab);
|
||||
|
|
|
@ -1514,6 +1514,7 @@
|
|||
var aSameProcessAsFrameLoader;
|
||||
var aOriginPrincipal;
|
||||
var aOpener;
|
||||
var aForceBrowserInsertion;
|
||||
if (arguments.length == 2 &&
|
||||
typeof arguments[1] == "object" &&
|
||||
!(arguments[1] instanceof Ci.nsIURI)) {
|
||||
|
@ -1537,6 +1538,7 @@
|
|||
aOriginPrincipal = params.originPrincipal;
|
||||
aOpener = params.opener;
|
||||
aIsPrerendered = params.isPrerendered;
|
||||
aForceBrowserInsertion = params.forceBrowserInsertion;
|
||||
}
|
||||
|
||||
var bgLoad = (aLoadInBackground != null) ? aLoadInBackground :
|
||||
|
@ -1556,6 +1558,7 @@
|
|||
skipAnimation: aSkipAnimation,
|
||||
allowMixedContent: aAllowMixedContent,
|
||||
forceNotRemote: aForceNotRemote,
|
||||
forceBrowserInsertion: aForceBrowserInsertion,
|
||||
preferredRemoteType: aPreferredRemoteType,
|
||||
noReferrer: aNoReferrer,
|
||||
userContextId: aUserContextId,
|
||||
|
@ -1710,6 +1713,9 @@
|
|||
}
|
||||
|
||||
let tab = this.getTabForBrowser(aBrowser);
|
||||
// aBrowser needs to be inserted now if it hasn't been already.
|
||||
this._insertBrowser(tab);
|
||||
|
||||
let evt = document.createEvent("Events");
|
||||
evt.initEvent("BeforeTabRemotenessChange", true, false);
|
||||
tab.dispatchEvent(evt);
|
||||
|
@ -1842,8 +1848,10 @@
|
|||
// If we're in a LargeAllocation process, we prefer switching back
|
||||
// into a normal content process, as that way we can clean up the
|
||||
// L-A process.
|
||||
let preferredRemoteType = aBrowser.remoteType;
|
||||
if (aBrowser.remoteType == E10SUtils.LARGE_ALLOCATION_REMOTE_TYPE) {
|
||||
let currentRemoteType = aBrowser.getAttribute("remoteType") || null;
|
||||
let preferredRemoteType = currentRemoteType;
|
||||
|
||||
if (currentRemoteType == E10SUtils.LARGE_ALLOCATION_REMOTE_TYPE) {
|
||||
preferredRemoteType = E10SUtils.DEFAULT_REMOTE_TYPE;
|
||||
}
|
||||
aOptions.remoteType =
|
||||
|
@ -1854,7 +1862,7 @@
|
|||
|
||||
// If this URL can't load in the current browser then flip it to the
|
||||
// correct type.
|
||||
if (aBrowser.remoteType != aOptions.remoteType ||
|
||||
if (currentRemoteType != aOptions.remoteType ||
|
||||
aOptions.newFrameloader) {
|
||||
let remote = aOptions.remoteType != E10SUtils.NOT_REMOTE;
|
||||
return this.updateBrowserRemoteness(aBrowser, remote, aOptions);
|
||||
|
@ -1943,12 +1951,12 @@
|
|||
<![CDATA[
|
||||
// Supported parameters:
|
||||
// userContextId, remote, remoteType, isPreloadBrowser,
|
||||
// uriIsAboutBlank, permanentKey, isPrerendered
|
||||
// uriIsAboutBlank, sameProcessAsFrameLoader, isPrerendered
|
||||
|
||||
const NS_XUL = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
|
||||
|
||||
let b = document.createElementNS(NS_XUL, "browser");
|
||||
b.permanentKey = aParams.permanentKey || {};
|
||||
b.permanentKey = {};
|
||||
b.setAttribute("type", "content");
|
||||
b.setAttribute("message", "true");
|
||||
b.setAttribute("messagemanagergroup", "browsers");
|
||||
|
@ -2034,59 +2042,92 @@
|
|||
</body>
|
||||
</method>
|
||||
|
||||
<method name="_linkBrowserToTab">
|
||||
<!--
|
||||
`_createLazyBrowser` will define properties on the unbound lazy browser
|
||||
which correspond to properties defined in XBL which will be bound to
|
||||
the browser when it is inserted into the document. If any of these
|
||||
properties are accessed by consumers, `_insertBrowser` is called and
|
||||
the browser is inserted to ensure that things don't break. This list
|
||||
provides the names of properties that may be called while the browser
|
||||
is in its unbound (lazy) state.
|
||||
-->
|
||||
<field name="_browserBindingProperties">[
|
||||
"canGoBack", "canGoForward", "goBack", "goForward", "permitUnload",
|
||||
"reload", "reloadWithFlags", "stop", "loadURI", "loadURIWithFlags",
|
||||
"goHome", "homePage", "gotoIndex", "currentURI", "documentURI",
|
||||
"preferences", "imageDocument", "isRemoteBrowser", "messageManager",
|
||||
"getTabBrowser", "finder", "fastFind", "sessionHistory", "contentTitle",
|
||||
"characterSet", "fullZoom", "textZoom", "webProgress",
|
||||
"addProgressListener", "removeProgressListener", "audioPlaybackStarted",
|
||||
"audioPlaybackStopped", "adjustPriority", "pauseMedia", "stopMedia",
|
||||
"blockMedia", "resumeMedia", "audioMuted", "mute", "unmute",
|
||||
"blockedPopups", "mIconURL", "lastURI", "userTypedValue",
|
||||
"purgeSessionHistory", "stopScroll", "startScroll"
|
||||
]</field>
|
||||
|
||||
<method name="_createLazyBrowser">
|
||||
<parameter name="aTab"/>
|
||||
<body>
|
||||
<![CDATA[
|
||||
let browser = aTab.linkedBrowser;
|
||||
|
||||
let names = this._browserBindingProperties;
|
||||
|
||||
for (let i = 0; i < names.length; i++) {
|
||||
let name = names[i];
|
||||
let getter;
|
||||
let setter;
|
||||
switch (name) {
|
||||
default:
|
||||
getter = () => {
|
||||
this._insertBrowser(aTab);
|
||||
return browser[name];
|
||||
};
|
||||
setter = (value) => {
|
||||
this._insertBrowser(aTab);
|
||||
return browser[name] = value;
|
||||
};
|
||||
}
|
||||
Object.defineProperty(browser, name, {
|
||||
get: getter,
|
||||
set: setter,
|
||||
configurable: true,
|
||||
enumerable: true
|
||||
});
|
||||
}
|
||||
]]>
|
||||
</body>
|
||||
</method>
|
||||
|
||||
<method name="_insertBrowser">
|
||||
<parameter name="aTab"/>
|
||||
<parameter name="aURI"/>
|
||||
<parameter name="aParams"/>
|
||||
<body>
|
||||
<![CDATA[
|
||||
"use strict";
|
||||
|
||||
// Supported parameters:
|
||||
// forceNotRemote, preferredRemoteType, userContextId, isPrerendered
|
||||
// If browser is already inserted, or aTab doesn't have a
|
||||
// browser, don't do anything.
|
||||
if (aTab.linkedPanel || !aTab.linkedBrowser) {
|
||||
return;
|
||||
}
|
||||
|
||||
let uriIsAboutBlank = !aURI || aURI == "about:blank";
|
||||
let browser = aTab.linkedBrowser;
|
||||
|
||||
let remoteType =
|
||||
aParams.forceNotRemote ? E10SUtils.NOT_REMOTE
|
||||
: E10SUtils.getRemoteTypeForURI(aURI, gMultiProcessBrowser,
|
||||
aParams.preferredRemoteType);
|
||||
|
||||
let browser;
|
||||
let usingPreloadedContent = false;
|
||||
|
||||
// If we open a new tab with the newtab URL in the default
|
||||
// userContext, check if there is a preloaded browser ready.
|
||||
// Private windows are not included because both the label and the
|
||||
// icon for the tab would be set incorrectly (see bug 1195981).
|
||||
if (aURI == BROWSER_NEW_TAB_URL &&
|
||||
!aParams.userContextId &&
|
||||
!PrivateBrowsingUtils.isWindowPrivate(window)) {
|
||||
browser = this._getPreloadedBrowser();
|
||||
if (browser) {
|
||||
usingPreloadedContent = true;
|
||||
aTab.permanentKey = browser.permanentKey;
|
||||
// If browser is a lazy browser, delete the substitute properties.
|
||||
if (this._browserBindingProperties[0] in browser) {
|
||||
for (let name of this._browserBindingProperties) {
|
||||
delete browser[name];
|
||||
}
|
||||
}
|
||||
|
||||
if (!browser) {
|
||||
// No preloaded browser found, create one.
|
||||
browser = this._createBrowser({permanentKey: aTab.permanentKey,
|
||||
remoteType,
|
||||
uriIsAboutBlank,
|
||||
userContextId: aParams.userContextId,
|
||||
sameProcessAsFrameLoader: aParams.sameProcessAsFrameLoader,
|
||||
opener: aParams.opener,
|
||||
isPrerendered: aParams.isPrerendered});
|
||||
}
|
||||
let { uriIsAboutBlank, remoteType, usingPreloadedContent } =
|
||||
aTab._browserParams;
|
||||
delete aTab._browserParams;
|
||||
|
||||
let notificationbox = this.getNotificationBox(browser);
|
||||
let uniqueId = this._generateUniquePanelID();
|
||||
notificationbox.id = uniqueId;
|
||||
aTab.linkedPanel = uniqueId;
|
||||
aTab.linkedBrowser = browser;
|
||||
aTab.hasBrowser = true;
|
||||
this._tabForBrowser.set(browser, aTab);
|
||||
|
||||
// Inject the <browser> into the DOM if necessary.
|
||||
if (!notificationbox.parentNode) {
|
||||
|
@ -2124,8 +2165,6 @@
|
|||
|
||||
var evt = new CustomEvent("TabBrowserInserted", { bubbles: true, detail: {} });
|
||||
aTab.dispatchEvent(evt);
|
||||
|
||||
return { usingPreloadedContent };
|
||||
]]>
|
||||
</body>
|
||||
</method>
|
||||
|
@ -2158,6 +2197,7 @@
|
|||
var aOriginPrincipal;
|
||||
var aDisallowInheritPrincipal;
|
||||
var aOpener;
|
||||
var aForceBrowserInsertion;
|
||||
if (arguments.length == 2 &&
|
||||
typeof arguments[1] == "object" &&
|
||||
!(arguments[1] instanceof Ci.nsIURI)) {
|
||||
|
@ -2183,6 +2223,7 @@
|
|||
aDisallowInheritPrincipal = params.disallowInheritPrincipal;
|
||||
aOpener = params.opener;
|
||||
aIsPrerendered = params.isPrerendered;
|
||||
aForceBrowserInsertion = params.forceBrowserInsertion;
|
||||
}
|
||||
|
||||
// if we're adding tabs, we're past interrupt mode, ditch the owner
|
||||
|
@ -2245,7 +2286,6 @@
|
|||
|
||||
var position = this.tabs.length - 1;
|
||||
t._tPos = position;
|
||||
t.permanentKey = {};
|
||||
this.tabContainer._setPositionalAttributes();
|
||||
|
||||
this.tabContainer.updateVisibility();
|
||||
|
@ -2259,23 +2299,51 @@
|
|||
gMultiProcessBrowser);
|
||||
}
|
||||
|
||||
// Currently in this incarnation of bug 906076, we are forcing the
|
||||
// browser to immediately be linked. In future incarnations of this
|
||||
// bug this will be removed so we can leave the tab in its "lazy"
|
||||
// state to be exploited for startup optimization. Note that for
|
||||
// now this must occur before "TabOpen" event is fired, as that will
|
||||
// trigger SessionStore.jsm to run code that expects the existence
|
||||
// of tab.linkedBrowser.
|
||||
let browserParams = {
|
||||
forceNotRemote: aForceNotRemote,
|
||||
preferredRemoteType: aPreferredRemoteType,
|
||||
let remoteType =
|
||||
aForceNotRemote ? E10SUtils.NOT_REMOTE
|
||||
: E10SUtils.getRemoteTypeForURI(aURI, gMultiProcessBrowser,
|
||||
aPreferredRemoteType);
|
||||
|
||||
let b;
|
||||
let usingPreloadedContent = false;
|
||||
|
||||
// If we open a new tab with the newtab URL in the default
|
||||
// userContext, check if there is a preloaded browser ready.
|
||||
// Private windows are not included because both the label and the
|
||||
// icon for the tab would be set incorrectly (see bug 1195981).
|
||||
if (aURI == BROWSER_NEW_TAB_URL &&
|
||||
!aUserContextId &&
|
||||
!PrivateBrowsingUtils.isWindowPrivate(window)) {
|
||||
b = this._getPreloadedBrowser();
|
||||
if (b) {
|
||||
usingPreloadedContent = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!b) {
|
||||
// No preloaded browser found, create one.
|
||||
b = this._createBrowser({ remoteType,
|
||||
uriIsAboutBlank,
|
||||
userContextId: aUserContextId,
|
||||
sameProcessAsFrameLoader: aSameProcessAsFrameLoader,
|
||||
opener: aOpener,
|
||||
isPrerendered: aIsPrerendered,
|
||||
};
|
||||
let { usingPreloadedContent } = this._linkBrowserToTab(t, aURI, browserParams);
|
||||
let b = t.linkedBrowser;
|
||||
isPrerendered: aIsPrerendered });
|
||||
}
|
||||
|
||||
t.linkedBrowser = b;
|
||||
this._tabForBrowser.set(b, t);
|
||||
t.permanentKey = b.permanentKey;
|
||||
t._browserParams = { uriIsAboutBlank,
|
||||
remoteType,
|
||||
usingPreloadedContent };
|
||||
|
||||
// If we're creating a blank tab, create a lazy browser.
|
||||
// Otherwise insert the browser into the document now.
|
||||
if (uriIsAboutBlank && !aForceBrowserInsertion) {
|
||||
this._createLazyBrowser(t);
|
||||
} else {
|
||||
this._insertBrowser(t);
|
||||
}
|
||||
|
||||
// Dispatch a new tab notification. We do this once we're
|
||||
// entirely done, so that things are in a consistent state
|
||||
|
@ -2495,6 +2563,9 @@
|
|||
var skipPermitUnload = aParams.skipPermitUnload;
|
||||
}
|
||||
|
||||
// Ensure aTab's browser is inserted into the document.
|
||||
this._insertBrowser(aTab);
|
||||
|
||||
window.maybeRecordAbandonmentTelemetry(aTab, "tabClosed");
|
||||
|
||||
// Handle requests for synchronously removing an already
|
||||
|
@ -2994,6 +3065,9 @@
|
|||
<parameter name="aStateFlags"/>
|
||||
<body>
|
||||
<![CDATA[
|
||||
// aOurTab's browser needs to be inserted now if it hasn't already.
|
||||
this._insertBrowser(aOurTab);
|
||||
|
||||
// Unhook our progress listener
|
||||
const filter = this._tabFilters.get(aOurTab);
|
||||
let tabListener = this._tabListeners.get(aOurTab);
|
||||
|
@ -4966,7 +5040,6 @@
|
|||
this.mCurrentTab._fullyOpen = true;
|
||||
this.mCurrentTab.cachePosition = 0;
|
||||
this.mCurrentTab.linkedBrowser = this.mCurrentBrowser;
|
||||
this.mCurrentTab.hasBrowser = true;
|
||||
this._tabForBrowser.set(this.mCurrentBrowser, this.mCurrentTab);
|
||||
|
||||
// set up the shared autoscroll popup
|
||||
|
@ -6282,6 +6355,21 @@
|
|||
</body>
|
||||
</method>
|
||||
|
||||
<method name="getRelatedElement">
|
||||
<parameter name="aTab"/>
|
||||
<body>
|
||||
<![CDATA[
|
||||
if (!aTab)
|
||||
return null;
|
||||
// If the tab's browser is lazy, we need to `_insertBrowser` in order
|
||||
// to have a linkedPanel. This will also serve to bind the browser
|
||||
// and make it ready to use when the tab is selected.
|
||||
this.tabbrowser._insertBrowser(aTab);
|
||||
return document.getElementById(aTab.linkedPanel);
|
||||
]]>
|
||||
</body>
|
||||
</method>
|
||||
|
||||
<!-- Deprecated stuff, implemented for backwards compatibility. -->
|
||||
<property name="mAllTabsPopup" readonly="true"
|
||||
onget="return document.getElementById('alltabs-popup');"/>
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
This is the pdf.js project output, https://github.com/mozilla/pdf.js
|
||||
|
||||
Current extension version is: 1.7.297
|
||||
Current extension version is: 1.7.312
|
||||
|
|
|
@ -221,6 +221,11 @@ var VERBOSITY_LEVELS = {
|
|||
warnings: 1,
|
||||
infos: 5
|
||||
};
|
||||
var CMapCompressionType = {
|
||||
NONE: 0,
|
||||
BINARY: 1,
|
||||
STREAM: 2
|
||||
};
|
||||
var OPS = {
|
||||
dependency: 1,
|
||||
setLineWidth: 2,
|
||||
|
@ -1166,6 +1171,12 @@ function isArrayBuffer(v) {
|
|||
function isSpace(ch) {
|
||||
return ch === 0x20 || ch === 0x09 || ch === 0x0D || ch === 0x0A;
|
||||
}
|
||||
function isNodeJS() {
|
||||
if (typeof __pdfjsdev_webpack__ === 'undefined') {
|
||||
return typeof process === 'object' && process + '' === '[object process]';
|
||||
}
|
||||
return false;
|
||||
}
|
||||
function createPromiseCapability() {
|
||||
var capability = {};
|
||||
capability.promise = new Promise(function (resolve, reject) {
|
||||
|
@ -1438,6 +1449,7 @@ exports.AnnotationFlag = AnnotationFlag;
|
|||
exports.AnnotationType = AnnotationType;
|
||||
exports.FontType = FontType;
|
||||
exports.ImageKind = ImageKind;
|
||||
exports.CMapCompressionType = CMapCompressionType;
|
||||
exports.InvalidPDFException = InvalidPDFException;
|
||||
exports.MessageHandler = MessageHandler;
|
||||
exports.MissingDataException = MissingDataException;
|
||||
|
@ -1474,6 +1486,7 @@ exports.isInt = isInt;
|
|||
exports.isNum = isNum;
|
||||
exports.isString = isString;
|
||||
exports.isSpace = isSpace;
|
||||
exports.isNodeJS = isNodeJS;
|
||||
exports.isSameOrigin = isSameOrigin;
|
||||
exports.createValidAbsoluteUrl = createValidAbsoluteUrl;
|
||||
exports.isLittleEndian = isLittleEndian;
|
||||
|
@ -1506,6 +1519,8 @@ var removeNullCharacters = sharedUtil.removeNullCharacters;
|
|||
var warn = sharedUtil.warn;
|
||||
var deprecated = sharedUtil.deprecated;
|
||||
var createValidAbsoluteUrl = sharedUtil.createValidAbsoluteUrl;
|
||||
var stringToBytes = sharedUtil.stringToBytes;
|
||||
var CMapCompressionType = sharedUtil.CMapCompressionType;
|
||||
var DEFAULT_LINK_REL = 'noopener noreferrer nofollow';
|
||||
function DOMCanvasFactory() {
|
||||
}
|
||||
|
@ -1535,6 +1550,48 @@ DOMCanvasFactory.prototype = {
|
|||
canvasAndContextPair.context = null;
|
||||
}
|
||||
};
|
||||
var DOMCMapReaderFactory = function DOMCMapReaderFactoryClosure() {
|
||||
function DOMCMapReaderFactory(params) {
|
||||
this.baseUrl = params.baseUrl || null;
|
||||
this.isCompressed = params.isCompressed || false;
|
||||
}
|
||||
DOMCMapReaderFactory.prototype = {
|
||||
fetch: function (params) {
|
||||
if (!params.name) {
|
||||
return Promise.reject(new Error('CMap name must be specified.'));
|
||||
}
|
||||
return new Promise(function (resolve, reject) {
|
||||
var url = this.baseUrl + params.name;
|
||||
var request = new XMLHttpRequest();
|
||||
if (this.isCompressed) {
|
||||
url += '.bcmap';
|
||||
request.responseType = 'arraybuffer';
|
||||
}
|
||||
request.onreadystatechange = function () {
|
||||
if (request.readyState === XMLHttpRequest.DONE && (request.status === 200 || request.status === 0)) {
|
||||
var data;
|
||||
if (this.isCompressed && request.response) {
|
||||
data = new Uint8Array(request.response);
|
||||
} else if (!this.isCompressed && request.responseText) {
|
||||
data = stringToBytes(request.responseText);
|
||||
}
|
||||
if (data) {
|
||||
resolve({
|
||||
cMapData: data,
|
||||
compressionType: this.isCompressed ? CMapCompressionType.BINARY : CMapCompressionType.NONE
|
||||
});
|
||||
return;
|
||||
}
|
||||
reject(new Error('Unable to load ' + (this.isCompressed ? 'binary' : '') + ' CMap at: ' + url));
|
||||
}
|
||||
}.bind(this);
|
||||
request.open('GET', url, true);
|
||||
request.send(null);
|
||||
}.bind(this));
|
||||
}
|
||||
};
|
||||
return DOMCMapReaderFactory;
|
||||
}();
|
||||
var CustomStyle = function CustomStyleClosure() {
|
||||
var prefixes = [
|
||||
'ms',
|
||||
|
@ -1694,6 +1751,7 @@ exports.hasCanvasTypedArrays = hasCanvasTypedArrays;
|
|||
exports.getDefaultSetting = getDefaultSetting;
|
||||
exports.DEFAULT_LINK_REL = DEFAULT_LINK_REL;
|
||||
exports.DOMCanvasFactory = DOMCanvasFactory;
|
||||
exports.DOMCMapReaderFactory = DOMCMapReaderFactory;
|
||||
|
||||
/***/ }),
|
||||
/* 2 */
|
||||
|
@ -2358,6 +2416,7 @@ var CanvasGraphics = displayCanvas.CanvasGraphics;
|
|||
var Metadata = displayMetadata.Metadata;
|
||||
var getDefaultSetting = displayDOMUtils.getDefaultSetting;
|
||||
var DOMCanvasFactory = displayDOMUtils.DOMCanvasFactory;
|
||||
var DOMCMapReaderFactory = displayDOMUtils.DOMCMapReaderFactory;
|
||||
var DEFAULT_RANGE_CHUNK_SIZE = 65536;
|
||||
var isWorkerDisabled = false;
|
||||
var workerSrc;
|
||||
|
@ -2431,6 +2490,7 @@ function getDocument(src, pdfDataRangeTransport, passwordCallback, progressCallb
|
|||
}
|
||||
params.rangeChunkSize = params.rangeChunkSize || DEFAULT_RANGE_CHUNK_SIZE;
|
||||
params.disableNativeImageDecoder = params.disableNativeImageDecoder === true;
|
||||
var CMapReaderFactory = params.CMapReaderFactory || DOMCMapReaderFactory;
|
||||
if (!worker) {
|
||||
worker = new PDFWorker();
|
||||
task._worker = worker;
|
||||
|
@ -2445,7 +2505,7 @@ function getDocument(src, pdfDataRangeTransport, passwordCallback, progressCallb
|
|||
throw new Error('Loading aborted');
|
||||
}
|
||||
var messageHandler = new MessageHandler(docId, workerId, worker.port);
|
||||
var transport = new WorkerTransport(messageHandler, task, rangeTransport);
|
||||
var transport = new WorkerTransport(messageHandler, task, rangeTransport, CMapReaderFactory);
|
||||
task._transport = transport;
|
||||
messageHandler.send('Ready', null);
|
||||
});
|
||||
|
@ -2468,8 +2528,6 @@ function _fetchDocument(worker, source, pdfDataRangeTransport, docId) {
|
|||
source: source,
|
||||
disableRange: getDefaultSetting('disableRange'),
|
||||
maxImageSize: getDefaultSetting('maxImageSize'),
|
||||
cMapUrl: getDefaultSetting('cMapUrl'),
|
||||
cMapPacked: getDefaultSetting('cMapPacked'),
|
||||
disableFontFace: getDefaultSetting('disableFontFace'),
|
||||
disableCreateObjectURL: getDefaultSetting('disableCreateObjectURL'),
|
||||
postMessageTransfers: getDefaultSetting('postMessageTransfers') && !isPostMessageTransfersDisabled,
|
||||
|
@ -3081,12 +3139,16 @@ var PDFWorker = function PDFWorkerClosure() {
|
|||
return PDFWorker;
|
||||
}();
|
||||
var WorkerTransport = function WorkerTransportClosure() {
|
||||
function WorkerTransport(messageHandler, loadingTask, pdfDataRangeTransport) {
|
||||
function WorkerTransport(messageHandler, loadingTask, pdfDataRangeTransport, CMapReaderFactory) {
|
||||
this.messageHandler = messageHandler;
|
||||
this.loadingTask = loadingTask;
|
||||
this.pdfDataRangeTransport = pdfDataRangeTransport;
|
||||
this.commonObjs = new PDFObjects();
|
||||
this.fontLoader = new FontLoader(loadingTask.docId);
|
||||
this.CMapReaderFactory = new CMapReaderFactory({
|
||||
baseUrl: getDefaultSetting('cMapUrl'),
|
||||
isCompressed: getDefaultSetting('cMapPacked')
|
||||
});
|
||||
this.destroyed = false;
|
||||
this.destroyCapability = null;
|
||||
this._passwordCapability = null;
|
||||
|
@ -3371,6 +3433,12 @@ var WorkerTransport = function WorkerTransportClosure() {
|
|||
img.src = imageUrl;
|
||||
});
|
||||
}, this);
|
||||
messageHandler.on('FetchBuiltInCMap', function (data) {
|
||||
if (this.destroyed) {
|
||||
return Promise.reject(new Error('Worker was destroyed'));
|
||||
}
|
||||
return this.CMapReaderFactory.fetch({ name: data.name });
|
||||
}, this);
|
||||
},
|
||||
getData: function WorkerTransport_getData() {
|
||||
return this.messageHandler.sendWithPromise('GetData', null);
|
||||
|
@ -3632,8 +3700,8 @@ var _UnsupportedManager = function UnsupportedManagerClosure() {
|
|||
}
|
||||
};
|
||||
}();
|
||||
exports.version = '1.7.297';
|
||||
exports.build = '425ad309';
|
||||
exports.version = '1.7.312';
|
||||
exports.build = 'cada411a';
|
||||
exports.getDocument = getDocument;
|
||||
exports.PDFDataRangeTransport = PDFDataRangeTransport;
|
||||
exports.PDFWorker = PDFWorker;
|
||||
|
@ -4650,8 +4718,8 @@ if (!globalScope.PDFJS) {
|
|||
globalScope.PDFJS = {};
|
||||
}
|
||||
var PDFJS = globalScope.PDFJS;
|
||||
PDFJS.version = '1.7.297';
|
||||
PDFJS.build = '425ad309';
|
||||
PDFJS.version = '1.7.312';
|
||||
PDFJS.build = 'cada411a';
|
||||
PDFJS.pdfBug = false;
|
||||
if (PDFJS.verbosity !== undefined) {
|
||||
sharedUtil.setVerbosityLevel(PDFJS.verbosity);
|
||||
|
@ -7143,8 +7211,8 @@ exports.TilingPattern = TilingPattern;
|
|||
|
||||
"use strict";
|
||||
|
||||
var pdfjsVersion = '1.7.297';
|
||||
var pdfjsBuild = '425ad309';
|
||||
var pdfjsVersion = '1.7.312';
|
||||
var pdfjsBuild = 'cada411a';
|
||||
var pdfjsSharedUtil = __w_pdfjs_require__(0);
|
||||
var pdfjsDisplayGlobal = __w_pdfjs_require__(8);
|
||||
var pdfjsDisplayAPI = __w_pdfjs_require__(3);
|
||||
|
|
|
@ -221,6 +221,11 @@ var VERBOSITY_LEVELS = {
|
|||
warnings: 1,
|
||||
infos: 5
|
||||
};
|
||||
var CMapCompressionType = {
|
||||
NONE: 0,
|
||||
BINARY: 1,
|
||||
STREAM: 2
|
||||
};
|
||||
var OPS = {
|
||||
dependency: 1,
|
||||
setLineWidth: 2,
|
||||
|
@ -1166,6 +1171,12 @@ function isArrayBuffer(v) {
|
|||
function isSpace(ch) {
|
||||
return ch === 0x20 || ch === 0x09 || ch === 0x0D || ch === 0x0A;
|
||||
}
|
||||
function isNodeJS() {
|
||||
if (typeof __pdfjsdev_webpack__ === 'undefined') {
|
||||
return typeof process === 'object' && process + '' === '[object process]';
|
||||
}
|
||||
return false;
|
||||
}
|
||||
function createPromiseCapability() {
|
||||
var capability = {};
|
||||
capability.promise = new Promise(function (resolve, reject) {
|
||||
|
@ -1438,6 +1449,7 @@ exports.AnnotationFlag = AnnotationFlag;
|
|||
exports.AnnotationType = AnnotationType;
|
||||
exports.FontType = FontType;
|
||||
exports.ImageKind = ImageKind;
|
||||
exports.CMapCompressionType = CMapCompressionType;
|
||||
exports.InvalidPDFException = InvalidPDFException;
|
||||
exports.MessageHandler = MessageHandler;
|
||||
exports.MissingDataException = MissingDataException;
|
||||
|
@ -1474,6 +1486,7 @@ exports.isInt = isInt;
|
|||
exports.isNum = isNum;
|
||||
exports.isString = isString;
|
||||
exports.isSpace = isSpace;
|
||||
exports.isNodeJS = isNodeJS;
|
||||
exports.isSameOrigin = isSameOrigin;
|
||||
exports.createValidAbsoluteUrl = createValidAbsoluteUrl;
|
||||
exports.isLittleEndian = isLittleEndian;
|
||||
|
@ -24787,6 +24800,7 @@ var UNSUPPORTED_FEATURES = sharedUtil.UNSUPPORTED_FEATURES;
|
|||
var ImageKind = sharedUtil.ImageKind;
|
||||
var OPS = sharedUtil.OPS;
|
||||
var TextRenderingMode = sharedUtil.TextRenderingMode;
|
||||
var CMapCompressionType = sharedUtil.CMapCompressionType;
|
||||
var Util = sharedUtil.Util;
|
||||
var assert = sharedUtil.assert;
|
||||
var createPromiseCapability = sharedUtil.createPromiseCapability;
|
||||
|
@ -24845,10 +24859,6 @@ var PartialEvaluator = function PartialEvaluatorClosure() {
|
|||
forceDataSchema: false,
|
||||
maxImageSize: -1,
|
||||
disableFontFace: false,
|
||||
cMapOptions: {
|
||||
url: null,
|
||||
packed: false
|
||||
},
|
||||
disableNativeImageDecoder: false
|
||||
};
|
||||
function NativeImageDecoder(xref, resources, handler, forceDataSchema) {
|
||||
|
@ -24892,14 +24902,27 @@ var PartialEvaluator = function PartialEvaluatorClosure() {
|
|||
var cs = ColorSpace.parse(dict.get('ColorSpace', 'CS'), xref, res);
|
||||
return (cs.numComps === 1 || cs.numComps === 3) && cs.isDefaultDecode(dict.getArray('Decode', 'D'));
|
||||
};
|
||||
function PartialEvaluator(pdfManager, xref, handler, pageIndex, idFactory, fontCache, options) {
|
||||
function PartialEvaluator(pdfManager, xref, handler, pageIndex, idFactory, fontCache, builtInCMapCache, options) {
|
||||
this.pdfManager = pdfManager;
|
||||
this.xref = xref;
|
||||
this.handler = handler;
|
||||
this.pageIndex = pageIndex;
|
||||
this.idFactory = idFactory;
|
||||
this.fontCache = fontCache;
|
||||
this.builtInCMapCache = builtInCMapCache;
|
||||
this.options = options || DefaultPartialEvaluatorOptions;
|
||||
this.fetchBuiltInCMap = function (name) {
|
||||
var cachedCMap = builtInCMapCache[name];
|
||||
if (cachedCMap) {
|
||||
return Promise.resolve(cachedCMap);
|
||||
}
|
||||
return handler.sendWithPromise('FetchBuiltInCMap', { name: name }).then(function (data) {
|
||||
if (data.compressionType !== CMapCompressionType.NONE) {
|
||||
builtInCMapCache[name] = data;
|
||||
}
|
||||
return data;
|
||||
});
|
||||
};
|
||||
}
|
||||
var TIME_SLOT_DURATION_MS = 20;
|
||||
var CHECK_TIME_EVERY = 100;
|
||||
|
@ -26236,7 +26259,11 @@ var PartialEvaluator = function PartialEvaluatorClosure() {
|
|||
var registry = properties.cidSystemInfo.registry;
|
||||
var ordering = properties.cidSystemInfo.ordering;
|
||||
var ucs2CMapName = Name.get(registry + '-' + ordering + '-UCS2');
|
||||
return CMapFactory.create(ucs2CMapName, this.options.cMapOptions, null).then(function (ucs2CMap) {
|
||||
return CMapFactory.create({
|
||||
encoding: ucs2CMapName,
|
||||
fetchBuiltInCMap: this.fetchBuiltInCMap,
|
||||
useCMap: null
|
||||
}).then(function (ucs2CMap) {
|
||||
var cMap = properties.cMap;
|
||||
toUnicode = [];
|
||||
cMap.forEach(function (charcode, cid) {
|
||||
|
@ -26254,14 +26281,22 @@ var PartialEvaluator = function PartialEvaluatorClosure() {
|
|||
readToUnicode: function PartialEvaluator_readToUnicode(toUnicode) {
|
||||
var cmapObj = toUnicode;
|
||||
if (isName(cmapObj)) {
|
||||
return CMapFactory.create(cmapObj, this.options.cMapOptions, null).then(function (cmap) {
|
||||
return CMapFactory.create({
|
||||
encoding: cmapObj,
|
||||
fetchBuiltInCMap: this.fetchBuiltInCMap,
|
||||
useCMap: null
|
||||
}).then(function (cmap) {
|
||||
if (cmap instanceof IdentityCMap) {
|
||||
return new IdentityToUnicodeMap(0, 0xFFFF);
|
||||
}
|
||||
return new ToUnicodeMap(cmap.getMap());
|
||||
});
|
||||
} else if (isStream(cmapObj)) {
|
||||
return CMapFactory.create(cmapObj, this.options.cMapOptions, null).then(function (cmap) {
|
||||
return CMapFactory.create({
|
||||
encoding: cmapObj,
|
||||
fetchBuiltInCMap: this.fetchBuiltInCMap,
|
||||
useCMap: null
|
||||
}).then(function (cmap) {
|
||||
if (cmap instanceof IdentityCMap) {
|
||||
return new IdentityToUnicodeMap(0, 0xFFFF);
|
||||
}
|
||||
|
@ -26524,7 +26559,6 @@ var PartialEvaluator = function PartialEvaluatorClosure() {
|
|||
var descriptor = preEvaluatedFont.descriptor;
|
||||
var type = preEvaluatedFont.type;
|
||||
var maxCharIndex = composite ? 0xFFFF : 0xFF;
|
||||
var cMapOptions = this.options.cMapOptions;
|
||||
var properties;
|
||||
if (!descriptor) {
|
||||
if (type === 'Type3') {
|
||||
|
@ -26619,7 +26653,11 @@ var PartialEvaluator = function PartialEvaluatorClosure() {
|
|||
if (isName(cidEncoding)) {
|
||||
properties.cidEncoding = cidEncoding.name;
|
||||
}
|
||||
cMapPromise = CMapFactory.create(cidEncoding, cMapOptions, null).then(function (cMap) {
|
||||
cMapPromise = CMapFactory.create({
|
||||
encoding: cidEncoding,
|
||||
fetchBuiltInCMap: this.fetchBuiltInCMap,
|
||||
useCMap: null
|
||||
}).then(function (cMap) {
|
||||
properties.cMap = cMap;
|
||||
properties.vertical = properties.cMap.vertical;
|
||||
});
|
||||
|
@ -29872,6 +29910,7 @@ var Catalog = function CatalogClosure() {
|
|||
this.xref = xref;
|
||||
this.catDict = xref.getCatalogObj();
|
||||
this.fontCache = new RefSetCache();
|
||||
this.builtInCMapCache = Object.create(null);
|
||||
assert(isDict(this.catDict), 'catalog object is not a dictionary');
|
||||
this.pageFactory = pageFactory;
|
||||
this.pagePromises = [];
|
||||
|
@ -30186,6 +30225,7 @@ var Catalog = function CatalogClosure() {
|
|||
delete font.translated;
|
||||
}
|
||||
this.fontCache.clear();
|
||||
this.builtInCMapCache = Object.create(null);
|
||||
}.bind(this));
|
||||
},
|
||||
getPage: function Catalog_getPage(pageIndex) {
|
||||
|
@ -30193,7 +30233,7 @@ var Catalog = function CatalogClosure() {
|
|||
this.pagePromises[pageIndex] = this.getPageDict(pageIndex).then(function (a) {
|
||||
var dict = a[0];
|
||||
var ref = a[1];
|
||||
return this.pageFactory.createPage(pageIndex, dict, ref, this.fontCache);
|
||||
return this.pageFactory.createPage(pageIndex, dict, ref, this.fontCache, this.builtInCMapCache);
|
||||
}.bind(this));
|
||||
}
|
||||
return this.pagePromises[pageIndex];
|
||||
|
@ -33926,6 +33966,7 @@ var error = sharedUtil.error;
|
|||
var info = sharedUtil.info;
|
||||
var warn = sharedUtil.warn;
|
||||
var setVerbosityLevel = sharedUtil.setVerbosityLevel;
|
||||
var isNodeJS = sharedUtil.isNodeJS;
|
||||
var Ref = corePrimitives.Ref;
|
||||
var LocalPdfManager = corePdfManager.LocalPdfManager;
|
||||
var NetworkPdfManager = corePdfManager.NetworkPdfManager;
|
||||
|
@ -34403,15 +34444,10 @@ var WorkerMessageHandler = {
|
|||
}, onFailure);
|
||||
}
|
||||
ensureNotTerminated();
|
||||
var cMapOptions = {
|
||||
url: data.cMapUrl === undefined ? null : data.cMapUrl,
|
||||
packed: data.cMapPacked === true
|
||||
};
|
||||
var evaluatorOptions = {
|
||||
forceDataSchema: data.disableCreateObjectURL,
|
||||
maxImageSize: data.maxImageSize === undefined ? -1 : data.maxImageSize,
|
||||
disableFontFace: data.disableFontFace,
|
||||
cMapOptions: cMapOptions,
|
||||
disableNativeImageDecoder: data.disableNativeImageDecoder
|
||||
};
|
||||
getPdfManager(data, evaluatorOptions).then(function (newPdfManager) {
|
||||
|
@ -34588,12 +34624,6 @@ function initializeWorker() {
|
|||
WorkerMessageHandler.setup(handler, self);
|
||||
handler.send('ready', null);
|
||||
}
|
||||
function isNodeJS() {
|
||||
if (typeof __pdfjsdev_webpack__ === 'undefined') {
|
||||
return typeof process === 'object' && process + '' === '[object process]';
|
||||
}
|
||||
return false;
|
||||
}
|
||||
if (typeof window === 'undefined' && !isNodeJS()) {
|
||||
initializeWorker();
|
||||
}
|
||||
|
@ -36580,11 +36610,12 @@ var error = sharedUtil.error;
|
|||
var isInt = sharedUtil.isInt;
|
||||
var isString = sharedUtil.isString;
|
||||
var MissingDataException = sharedUtil.MissingDataException;
|
||||
var CMapCompressionType = sharedUtil.CMapCompressionType;
|
||||
var isEOF = corePrimitives.isEOF;
|
||||
var isName = corePrimitives.isName;
|
||||
var isCmd = corePrimitives.isCmd;
|
||||
var isStream = corePrimitives.isStream;
|
||||
var StringStream = coreStream.StringStream;
|
||||
var Stream = coreStream.Stream;
|
||||
var Lexer = coreParser.Lexer;
|
||||
var BUILT_IN_CMAPS = [
|
||||
'Adobe-GB1-UCS2',
|
||||
|
@ -36919,23 +36950,6 @@ var IdentityCMap = function IdentityCMapClosure() {
|
|||
return IdentityCMap;
|
||||
}();
|
||||
var BinaryCMapReader = function BinaryCMapReaderClosure() {
|
||||
function fetchBinaryData(url) {
|
||||
return new Promise(function (resolve, reject) {
|
||||
var request = new XMLHttpRequest();
|
||||
request.open('GET', url, true);
|
||||
request.responseType = 'arraybuffer';
|
||||
request.onreadystatechange = function () {
|
||||
if (request.readyState === XMLHttpRequest.DONE) {
|
||||
if (!request.response || request.status !== 200 && request.status !== 0) {
|
||||
reject(new Error('Unable to get binary cMap at: ' + url));
|
||||
} else {
|
||||
resolve(new Uint8Array(request.response));
|
||||
}
|
||||
}
|
||||
};
|
||||
request.send(null);
|
||||
});
|
||||
}
|
||||
function hexToInt(a, size) {
|
||||
var n = 0;
|
||||
for (var i = 0; i <= size; i++) {
|
||||
|
@ -37045,8 +37059,8 @@ var BinaryCMapReader = function BinaryCMapReaderClosure() {
|
|||
return s;
|
||||
}
|
||||
};
|
||||
function processBinaryCMap(url, cMap, extend) {
|
||||
return fetchBinaryData(url).then(function (data) {
|
||||
function processBinaryCMap(data, cMap, extend) {
|
||||
return new Promise(function (resolve, reject) {
|
||||
var stream = new BinaryCMapStream(data);
|
||||
var header = stream.readByte();
|
||||
cMap.vertical = !!(header & 1);
|
||||
|
@ -37177,19 +37191,20 @@ var BinaryCMapReader = function BinaryCMapReaderClosure() {
|
|||
}
|
||||
break;
|
||||
default:
|
||||
error('Unknown type: ' + type);
|
||||
break;
|
||||
reject(new Error('processBinaryCMap: Unknown type: ' + type));
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (useCMap) {
|
||||
return extend(useCMap);
|
||||
resolve(extend(useCMap));
|
||||
return;
|
||||
}
|
||||
return cMap;
|
||||
resolve(cMap);
|
||||
});
|
||||
}
|
||||
function BinaryCMapReader() {
|
||||
}
|
||||
BinaryCMapReader.prototype = { read: processBinaryCMap };
|
||||
BinaryCMapReader.prototype = { process: processBinaryCMap };
|
||||
return BinaryCMapReader;
|
||||
}();
|
||||
var CMapFactory = function CMapFactoryClosure() {
|
||||
|
@ -37330,7 +37345,7 @@ var CMapFactory = function CMapFactoryClosure() {
|
|||
cMap.name = obj.name;
|
||||
}
|
||||
}
|
||||
function parseCMap(cMap, lexer, builtInCMapParams, useCMap) {
|
||||
function parseCMap(cMap, lexer, fetchBuiltInCMap, useCMap) {
|
||||
var previous;
|
||||
var embededUseCMap;
|
||||
objLoop:
|
||||
|
@ -37384,12 +37399,12 @@ var CMapFactory = function CMapFactoryClosure() {
|
|||
useCMap = embededUseCMap;
|
||||
}
|
||||
if (useCMap) {
|
||||
return extendCMap(cMap, builtInCMapParams, useCMap);
|
||||
return extendCMap(cMap, fetchBuiltInCMap, useCMap);
|
||||
}
|
||||
return Promise.resolve(cMap);
|
||||
}
|
||||
function extendCMap(cMap, builtInCMapParams, useCMap) {
|
||||
return createBuiltInCMap(useCMap, builtInCMapParams).then(function (newCMap) {
|
||||
function extendCMap(cMap, fetchBuiltInCMap, useCMap) {
|
||||
return createBuiltInCMap(useCMap, fetchBuiltInCMap).then(function (newCMap) {
|
||||
cMap.useCMap = newCMap;
|
||||
if (cMap.numCodespaceRanges === 0) {
|
||||
var useCodespaceRanges = cMap.useCMap.codespaceRanges;
|
||||
|
@ -37406,14 +37421,7 @@ var CMapFactory = function CMapFactoryClosure() {
|
|||
return cMap;
|
||||
});
|
||||
}
|
||||
function parseBinaryCMap(name, builtInCMapParams) {
|
||||
var url = builtInCMapParams.url + name + '.bcmap';
|
||||
var cMap = new CMap(true);
|
||||
return new BinaryCMapReader().read(url, cMap, function (useCMap) {
|
||||
return extendCMap(cMap, builtInCMapParams, useCMap);
|
||||
});
|
||||
}
|
||||
function createBuiltInCMap(name, builtInCMapParams) {
|
||||
function createBuiltInCMap(name, fetchBuiltInCMap) {
|
||||
if (name === 'Identity-H') {
|
||||
return Promise.resolve(new IdentityCMap(false, 2));
|
||||
} else if (name === 'Identity-V') {
|
||||
|
@ -37422,40 +37430,33 @@ var CMapFactory = function CMapFactoryClosure() {
|
|||
if (BUILT_IN_CMAPS.indexOf(name) === -1) {
|
||||
return Promise.reject(new Error('Unknown cMap name: ' + name));
|
||||
}
|
||||
assert(builtInCMapParams, 'built-in cMap parameters are not provided');
|
||||
if (builtInCMapParams.packed) {
|
||||
return parseBinaryCMap(name, builtInCMapParams);
|
||||
}
|
||||
return new Promise(function (resolve, reject) {
|
||||
var url = builtInCMapParams.url + name;
|
||||
var request = new XMLHttpRequest();
|
||||
request.onreadystatechange = function () {
|
||||
if (request.readyState === XMLHttpRequest.DONE) {
|
||||
if (request.status === 200 || request.status === 0) {
|
||||
assert(fetchBuiltInCMap, 'Built-in CMap parameters are not provided.');
|
||||
return fetchBuiltInCMap(name).then(function (data) {
|
||||
var cMapData = data.cMapData, compressionType = data.compressionType;
|
||||
var cMap = new CMap(true);
|
||||
var lexer = new Lexer(new StringStream(request.responseText));
|
||||
parseCMap(cMap, lexer, builtInCMapParams, null).then(function (parsedCMap) {
|
||||
resolve(parsedCMap);
|
||||
if (compressionType === CMapCompressionType.BINARY) {
|
||||
return new BinaryCMapReader().process(cMapData, cMap, function (useCMap) {
|
||||
return extendCMap(cMap, fetchBuiltInCMap, useCMap);
|
||||
});
|
||||
} else {
|
||||
reject(new Error('Unable to get cMap at: ' + url));
|
||||
}
|
||||
}
|
||||
};
|
||||
request.open('GET', url, true);
|
||||
request.send(null);
|
||||
assert(compressionType === CMapCompressionType.NONE, 'TODO: Only BINARY/NONE CMap compression is currently supported.');
|
||||
var lexer = new Lexer(new Stream(cMapData));
|
||||
return parseCMap(cMap, lexer, fetchBuiltInCMap, null);
|
||||
});
|
||||
}
|
||||
return {
|
||||
create: function (encoding, builtInCMapParams, useCMap) {
|
||||
create: function (params) {
|
||||
var encoding = params.encoding;
|
||||
var fetchBuiltInCMap = params.fetchBuiltInCMap;
|
||||
var useCMap = params.useCMap;
|
||||
if (isName(encoding)) {
|
||||
return createBuiltInCMap(encoding.name, builtInCMapParams);
|
||||
return createBuiltInCMap(encoding.name, fetchBuiltInCMap);
|
||||
} else if (isStream(encoding)) {
|
||||
var cMap = new CMap();
|
||||
var lexer = new Lexer(encoding);
|
||||
return parseCMap(cMap, lexer, builtInCMapParams, useCMap).then(function (parsedCMap) {
|
||||
return parseCMap(cMap, lexer, fetchBuiltInCMap, useCMap).then(function (parsedCMap) {
|
||||
if (parsedCMap.isIdentityCMap) {
|
||||
return createBuiltInCMap(parsedCMap.name, builtInCMapParams);
|
||||
return createBuiltInCMap(parsedCMap.name, fetchBuiltInCMap);
|
||||
}
|
||||
return parsedCMap;
|
||||
});
|
||||
|
@ -37520,13 +37521,14 @@ var Page = function PageClosure() {
|
|||
612,
|
||||
792
|
||||
];
|
||||
function Page(pdfManager, xref, pageIndex, pageDict, ref, fontCache) {
|
||||
function Page(pdfManager, xref, pageIndex, pageDict, ref, fontCache, builtInCMapCache) {
|
||||
this.pdfManager = pdfManager;
|
||||
this.pageIndex = pageIndex;
|
||||
this.pageDict = pageDict;
|
||||
this.xref = xref;
|
||||
this.ref = ref;
|
||||
this.fontCache = fontCache;
|
||||
this.builtInCMapCache = builtInCMapCache;
|
||||
this.evaluatorOptions = pdfManager.evaluatorOptions;
|
||||
this.resourcesPromise = null;
|
||||
var uniquePrefix = 'p' + this.pageIndex + '_';
|
||||
|
@ -37652,7 +37654,7 @@ var Page = function PageClosure() {
|
|||
'XObject',
|
||||
'Font'
|
||||
]);
|
||||
var partialEvaluator = new PartialEvaluator(pdfManager, this.xref, handler, this.pageIndex, this.idFactory, this.fontCache, this.evaluatorOptions);
|
||||
var partialEvaluator = new PartialEvaluator(pdfManager, this.xref, handler, this.pageIndex, this.idFactory, this.fontCache, this.builtInCMapCache, this.evaluatorOptions);
|
||||
var dataPromises = Promise.all([
|
||||
contentStreamPromise,
|
||||
resourcesPromise
|
||||
|
@ -37708,7 +37710,7 @@ var Page = function PageClosure() {
|
|||
]);
|
||||
return dataPromises.then(function (data) {
|
||||
var contentStream = data[0];
|
||||
var partialEvaluator = new PartialEvaluator(pdfManager, self.xref, handler, self.pageIndex, self.idFactory, self.fontCache, self.evaluatorOptions);
|
||||
var partialEvaluator = new PartialEvaluator(pdfManager, self.xref, handler, self.pageIndex, self.idFactory, self.fontCache, self.builtInCMapCache, self.evaluatorOptions);
|
||||
return partialEvaluator.getTextContent(contentStream, task, self.resources, null, normalizeWhitespace, combineTextItems);
|
||||
});
|
||||
},
|
||||
|
@ -37901,8 +37903,8 @@ var PDFDocument = function PDFDocumentClosure() {
|
|||
this.xref.parse(recoveryMode);
|
||||
var self = this;
|
||||
var pageFactory = {
|
||||
createPage: function (pageIndex, dict, ref, fontCache) {
|
||||
return new Page(self.pdfManager, self.xref, pageIndex, dict, ref, fontCache);
|
||||
createPage: function (pageIndex, dict, ref, fontCache, builtInCMapCache) {
|
||||
return new Page(self.pdfManager, self.xref, pageIndex, dict, ref, fontCache, builtInCMapCache);
|
||||
}
|
||||
};
|
||||
this.catalog = new Catalog(this.pdfManager, this.xref, pageFactory);
|
||||
|
@ -49174,8 +49176,8 @@ exports.Type1Parser = Type1Parser;
|
|||
|
||||
"use strict";
|
||||
|
||||
var pdfjsVersion = '1.7.297';
|
||||
var pdfjsBuild = '425ad309';
|
||||
var pdfjsVersion = '1.7.312';
|
||||
var pdfjsBuild = 'cada411a';
|
||||
var pdfjsCoreWorker = __w_pdfjs_require__(17);
|
||||
;
|
||||
exports.WorkerMessageHandler = pdfjsCoreWorker.WorkerMessageHandler;
|
||||
|
|
|
@ -321,8 +321,11 @@ function getVisibleElements(scrollEl, views, sortByVisibility) {
|
|||
function noContextMenuHandler(e) {
|
||||
e.preventDefault();
|
||||
}
|
||||
function getPDFFileNameFromURL(url) {
|
||||
var reURI = /^(?:([^:]+:)?\/\/[^\/]+)?([^?#]*)(\?[^#]*)?(#.*)?$/;
|
||||
function getPDFFileNameFromURL(url, defaultFilename) {
|
||||
if (typeof defaultFilename === 'undefined') {
|
||||
defaultFilename = 'document.pdf';
|
||||
}
|
||||
var reURI = /^(?:(?:[^:]+:)?\/\/[^\/]+)?([^?#]*)(\?[^#]*)?(#.*)?$/;
|
||||
var reFilename = /[^\/?#=]+\.pdf\b(?!.*\.pdf\b)/i;
|
||||
var splitURI = reURI.exec(url);
|
||||
var suggestedFilename = reFilename.exec(splitURI[1]) || reFilename.exec(splitURI[2]) || reFilename.exec(splitURI[3]);
|
||||
|
@ -335,7 +338,7 @@ function getPDFFileNameFromURL(url) {
|
|||
}
|
||||
}
|
||||
}
|
||||
return suggestedFilename || 'document.pdf';
|
||||
return suggestedFilename || defaultFilename;
|
||||
}
|
||||
function normalizeWheelEventDelta(evt) {
|
||||
var delta = Math.sqrt(evt.deltaX * evt.deltaX + evt.deltaY * evt.deltaY);
|
||||
|
@ -1148,11 +1151,15 @@ var PDFViewerApplication = {
|
|||
setTitleUsingUrl: function pdfViewSetTitleUsingUrl(url) {
|
||||
this.url = url;
|
||||
this.baseUrl = url.split('#')[0];
|
||||
var title = getPDFFileNameFromURL(url, '');
|
||||
if (!title) {
|
||||
try {
|
||||
this.setTitle(decodeURIComponent(pdfjsLib.getFilenameFromUrl(url)) || url);
|
||||
title = decodeURIComponent(pdfjsLib.getFilenameFromUrl(url)) || url;
|
||||
} catch (e) {
|
||||
this.setTitle(url);
|
||||
title = url;
|
||||
}
|
||||
}
|
||||
this.setTitle(title);
|
||||
},
|
||||
setTitle: function pdfViewSetTitle(title) {
|
||||
if (this.isViewerEmbedded) {
|
||||
|
@ -1251,7 +1258,7 @@ var PDFViewerApplication = {
|
|||
downloadManager.downloadUrl(url, filename);
|
||||
}
|
||||
var url = this.baseUrl;
|
||||
var filename = getPDFFileNameFromURL(url);
|
||||
var filename = getPDFFileNameFromURL(this.url);
|
||||
var downloadManager = this.downloadManager;
|
||||
downloadManager.onerror = function (err) {
|
||||
PDFViewerApplication.error('PDF failed to download.');
|
||||
|
@ -3896,6 +3903,18 @@ var PDFAttachmentViewer = function PDFAttachmentViewerClosure() {
|
|||
});
|
||||
this._renderedCapability.resolve();
|
||||
},
|
||||
_bindPdfLink: function PDFAttachmentViewer_bindPdfLink(button, content, filename) {
|
||||
var blobUrl;
|
||||
button.onclick = function () {
|
||||
if (!blobUrl) {
|
||||
blobUrl = pdfjsLib.createObjectURL(content, 'application/pdf', pdfjsLib.PDFJS.disableCreateObjectURL);
|
||||
}
|
||||
var viewerUrl;
|
||||
viewerUrl = blobUrl + '?' + encodeURIComponent(filename);
|
||||
window.open(viewerUrl);
|
||||
return false;
|
||||
};
|
||||
},
|
||||
_bindLink: function PDFAttachmentViewer_bindLink(button, content, filename) {
|
||||
button.onclick = function downloadFile(e) {
|
||||
this.downloadManager.downloadData(content, filename, '');
|
||||
|
@ -3922,11 +3941,16 @@ var PDFAttachmentViewer = function PDFAttachmentViewerClosure() {
|
|||
for (var i = 0; i < attachmentsCount; i++) {
|
||||
var item = attachments[names[i]];
|
||||
var filename = pdfjsLib.getFilenameFromUrl(item.filename);
|
||||
filename = pdfjsLib.removeNullCharacters(filename);
|
||||
var div = document.createElement('div');
|
||||
div.className = 'attachmentsItem';
|
||||
var button = document.createElement('button');
|
||||
button.textContent = filename;
|
||||
if (/\.pdf$/i.test(filename)) {
|
||||
this._bindPdfLink(button, item.content, filename);
|
||||
} else {
|
||||
this._bindLink(button, item.content, filename);
|
||||
button.textContent = pdfjsLib.removeNullCharacters(filename);
|
||||
}
|
||||
div.appendChild(button);
|
||||
this.container.appendChild(div);
|
||||
}
|
||||
|
|
|
@ -61,7 +61,7 @@ def Library(name):
|
|||
|
||||
|
||||
@template
|
||||
def RustLibrary(name, features=None):
|
||||
def RustLibrary(name, features=None, target_dir=None):
|
||||
'''Template for Rust libraries.'''
|
||||
Library(name)
|
||||
|
||||
|
@ -70,6 +70,9 @@ def RustLibrary(name, features=None):
|
|||
if features:
|
||||
RUST_LIBRARY_FEATURES = features
|
||||
|
||||
if target_dir:
|
||||
RUST_LIBRARY_TARGET_DIR = target_dir
|
||||
|
||||
|
||||
@template
|
||||
def SharedLibrary(name):
|
||||
|
|
|
@ -166,25 +166,43 @@ nsNullPrincipal::Read(nsIObjectInputStream* aStream)
|
|||
// that the Init() method has already been invoked by the time we deserialize.
|
||||
// This is in contrast to nsPrincipal, which uses NS_GENERIC_FACTORY_CONSTRUCTOR,
|
||||
// in which case ::Read needs to invoke Init().
|
||||
nsAutoCString suffix;
|
||||
nsresult rv = aStream->ReadCString(suffix);
|
||||
|
||||
nsAutoCString spec;
|
||||
nsresult rv = aStream->ReadCString(spec);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
bool ok = mOriginAttributes.PopulateFromSuffix(suffix);
|
||||
nsCOMPtr<nsIURI> uri;
|
||||
rv = NS_NewURI(getter_AddRefs(uri), spec);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsAutoCString suffix;
|
||||
rv = aStream->ReadCString(suffix);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
OriginAttributes attrs;
|
||||
bool ok = attrs.PopulateFromSuffix(suffix);
|
||||
NS_ENSURE_TRUE(ok, NS_ERROR_FAILURE);
|
||||
|
||||
return NS_OK;
|
||||
return Init(attrs, uri);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsNullPrincipal::Write(nsIObjectOutputStream* aStream)
|
||||
{
|
||||
NS_ENSURE_STATE(mURI);
|
||||
|
||||
nsAutoCString spec;
|
||||
nsresult rv = mURI->GetSpec(spec);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = aStream->WriteStringZ(spec.get());
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsAutoCString suffix;
|
||||
OriginAttributesRef().CreateSuffix(suffix);
|
||||
|
||||
nsresult rv = aStream->WriteStringZ(suffix.get());
|
||||
rv = aStream->WriteStringZ(suffix.get());
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -936,7 +936,7 @@ rustflags_override = RUSTFLAGS='$(rustflags)'
|
|||
endif
|
||||
|
||||
CARGO_BUILD = env $(rustflags_override) \
|
||||
CARGO_TARGET_DIR=. \
|
||||
CARGO_TARGET_DIR=$(CARGO_TARGET_DIR) \
|
||||
RUSTC=$(RUSTC) \
|
||||
MOZ_DIST=$(ABS_DIST) \
|
||||
LIBCLANG_PATH=$(MOZ_LIBCLANG_PATH) \
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
/* 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 { createEnum } = require("devtools/client/shared/enum");
|
||||
|
||||
createEnum([
|
||||
|
||||
// Update the layout state with the latest layout properties.
|
||||
"UPDATE_LAYOUT",
|
||||
|
||||
], module.exports);
|
|
@ -0,0 +1,10 @@
|
|||
# -*- 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/.
|
||||
|
||||
DevToolsModules(
|
||||
'box-model.js',
|
||||
'index.js',
|
||||
)
|
|
@ -0,0 +1,301 @@
|
|||
/* 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 { Task } = require("devtools/shared/task");
|
||||
const { getCssProperties } = require("devtools/shared/fronts/css-properties");
|
||||
const { ReflowFront } = require("devtools/shared/fronts/reflow");
|
||||
|
||||
const { InplaceEditor } = require("devtools/client/shared/inplace-editor");
|
||||
|
||||
const { updateLayout } = require("./actions/box-model");
|
||||
|
||||
const EditingSession = require("./utils/editing-session");
|
||||
|
||||
const NUMERIC = /^-?[\d\.]+$/;
|
||||
|
||||
/**
|
||||
* A singleton instance of the box model controllers.
|
||||
*
|
||||
* @param {Inspector} inspector
|
||||
* An instance of the Inspector currently loaded in the toolbox.
|
||||
* @param {Window} window
|
||||
* The document window of the toolbox.
|
||||
*/
|
||||
function BoxModel(inspector, window) {
|
||||
this.document = window.document;
|
||||
this.inspector = inspector;
|
||||
this.store = inspector.store;
|
||||
|
||||
this.updateBoxModel = this.updateBoxModel.bind(this);
|
||||
|
||||
this.onHideBoxModelHighlighter = this.onHideBoxModelHighlighter.bind(this);
|
||||
this.onNewSelection = this.onNewSelection.bind(this);
|
||||
this.onShowBoxModelEditor = this.onShowBoxModelEditor.bind(this);
|
||||
this.onShowBoxModelHighlighter = this.onShowBoxModelHighlighter.bind(this);
|
||||
this.onSidebarSelect = this.onSidebarSelect.bind(this);
|
||||
|
||||
this.inspector.selection.on("new-node-front", this.onNewSelection);
|
||||
this.inspector.sidebar.on("select", this.onSidebarSelect);
|
||||
}
|
||||
|
||||
BoxModel.prototype = {
|
||||
|
||||
/**
|
||||
* Destruction function called when the inspector is destroyed. Removes event listeners
|
||||
* and cleans up references.
|
||||
*/
|
||||
destroy() {
|
||||
this.inspector.selection.off("new-node-front", this.onNewSelection);
|
||||
this.inspector.sidebar.off("select", this.onSidebarSelect);
|
||||
|
||||
if (this.reflowFront) {
|
||||
this.untrackReflows();
|
||||
this.reflowFront.destroy();
|
||||
this.reflowFront = null;
|
||||
}
|
||||
|
||||
this.document = null;
|
||||
this.inspector = null;
|
||||
this.walker = null;
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns an object containing the box model's handler functions used in the box
|
||||
* model's React component props.
|
||||
*/
|
||||
getComponentProps() {
|
||||
return {
|
||||
onHideBoxModelHighlighter: this.onHideBoxModelHighlighter,
|
||||
onShowBoxModelEditor: this.onShowBoxModelEditor,
|
||||
onShowBoxModelHighlighter: this.onShowBoxModelHighlighter,
|
||||
};
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns true if the computed or layout panel is visible, and false otherwise.
|
||||
*/
|
||||
isPanelVisible() {
|
||||
return this.inspector.toolbox.currentToolId === "inspector" &&
|
||||
this.inspector.sidebar &&
|
||||
(this.inspector.sidebar.getCurrentTabID() === "layoutview" ||
|
||||
this.inspector.sidebar.getCurrentTabID() === "computedview");
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns true if the layout panel is visible and the current node is valid to
|
||||
* be displayed in the view.
|
||||
*/
|
||||
isPanelVisibleAndNodeValid() {
|
||||
return this.isPanelVisible() &&
|
||||
this.inspector.selection.isConnected() &&
|
||||
this.inspector.selection.isElementNode();
|
||||
},
|
||||
|
||||
/**
|
||||
* Starts listening to reflows in the current tab.
|
||||
*/
|
||||
trackReflows() {
|
||||
if (!this.reflowFront) {
|
||||
let { target } = this.inspector;
|
||||
if (target.form.reflowActor) {
|
||||
this.reflowFront = ReflowFront(target.client,
|
||||
target.form);
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
this.reflowFront.on("reflows", this.updateBoxModel);
|
||||
this.reflowFront.start();
|
||||
},
|
||||
|
||||
/**
|
||||
* Stops listening to reflows in the current tab.
|
||||
*/
|
||||
untrackReflows() {
|
||||
if (!this.reflowFront) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.reflowFront.off("reflows", this.updateBoxModel);
|
||||
this.reflowFront.stop();
|
||||
},
|
||||
|
||||
/**
|
||||
* Updates the box model panel by dispatching the new layout data.
|
||||
*
|
||||
* @param {String} reason
|
||||
* Optional string describing the reason why the boxmodel is updated.
|
||||
*/
|
||||
updateBoxModel(reason) {
|
||||
this._updateReasons = this._updateReasons || [];
|
||||
if (reason) {
|
||||
this._updateReasons.push(reason);
|
||||
}
|
||||
|
||||
let lastRequest = Task.spawn((function* () {
|
||||
if (!(this.isPanelVisible() &&
|
||||
this.inspector.selection.isConnected() &&
|
||||
this.inspector.selection.isElementNode())) {
|
||||
return null;
|
||||
}
|
||||
|
||||
let node = this.inspector.selection.nodeFront;
|
||||
let layout = yield this.inspector.pageStyle.getLayout(node, {
|
||||
autoMargins: true,
|
||||
});
|
||||
let styleEntries = yield this.inspector.pageStyle.getApplied(node, {});
|
||||
this.elementRules = styleEntries.map(e => e.rule);
|
||||
|
||||
// Update the redux store with the latest layout properties and update the box
|
||||
// model view.
|
||||
this.store.dispatch(updateLayout(layout));
|
||||
|
||||
// If a subsequent request has been made, wait for that one instead.
|
||||
if (this._lastRequest != lastRequest) {
|
||||
return this._lastRequest;
|
||||
}
|
||||
|
||||
this.inspector.emit("boxmodel-view-updated", this._updateReasons);
|
||||
|
||||
this._lastRequest = null;
|
||||
this._updateReasons = [];
|
||||
|
||||
return null;
|
||||
}).bind(this)).catch(console.error);
|
||||
|
||||
this._lastRequest = lastRequest;
|
||||
},
|
||||
|
||||
/**
|
||||
* Selection 'new-node-front' event handler.
|
||||
*/
|
||||
onNewSelection: function () {
|
||||
if (!this.isPanelVisibleAndNodeValid()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.inspector.selection.isConnected() &&
|
||||
this.inspector.selection.isElementNode()) {
|
||||
this.trackReflows();
|
||||
}
|
||||
|
||||
this.updateBoxModel("new-selection");
|
||||
},
|
||||
|
||||
/**
|
||||
* Hides the box-model highlighter on the currently selected element.
|
||||
*/
|
||||
onHideBoxModelHighlighter() {
|
||||
let toolbox = this.inspector.toolbox;
|
||||
toolbox.highlighterUtils.unhighlight();
|
||||
},
|
||||
|
||||
/**
|
||||
* Shows the inplace editor when a box model editable value is clicked on the
|
||||
* box model panel.
|
||||
*
|
||||
* @param {DOMNode} element
|
||||
* The element that was clicked.
|
||||
* @param {Event} event
|
||||
* The event object.
|
||||
* @param {String} property
|
||||
* The name of the property.
|
||||
*/
|
||||
onShowBoxModelEditor(element, event, property) {
|
||||
let session = new EditingSession({
|
||||
inspector: this.inspector,
|
||||
doc: this.document,
|
||||
elementRules: this.elementRules,
|
||||
});
|
||||
let initialValue = session.getProperty(property);
|
||||
|
||||
let editor = new InplaceEditor({
|
||||
element: element,
|
||||
initial: initialValue,
|
||||
contentType: InplaceEditor.CONTENT_TYPES.CSS_VALUE,
|
||||
property: {
|
||||
name: property
|
||||
},
|
||||
start: self => {
|
||||
self.elt.parentNode.classList.add("boxmodel-editing");
|
||||
},
|
||||
change: value => {
|
||||
if (NUMERIC.test(value)) {
|
||||
value += "px";
|
||||
}
|
||||
|
||||
let properties = [
|
||||
{ name: property, value: value }
|
||||
];
|
||||
|
||||
if (property.substring(0, 7) == "border-") {
|
||||
let bprop = property.substring(0, property.length - 5) + "style";
|
||||
let style = session.getProperty(bprop);
|
||||
if (!style || style == "none" || style == "hidden") {
|
||||
properties.push({ name: bprop, value: "solid" });
|
||||
}
|
||||
}
|
||||
|
||||
session.setProperties(properties).catch(e => console.error(e));
|
||||
},
|
||||
done: (value, commit) => {
|
||||
editor.elt.parentNode.classList.remove("boxmodel-editing");
|
||||
if (!commit) {
|
||||
session.revert().then(() => {
|
||||
session.destroy();
|
||||
}, e => console.error(e));
|
||||
return;
|
||||
}
|
||||
|
||||
let node = this.inspector.selection.nodeFront;
|
||||
this.inspector.pageStyle.getLayout(node, {
|
||||
autoMargins: true,
|
||||
}).then(layout => {
|
||||
this.store.dispatch(updateLayout(layout));
|
||||
}, e => console.error(e));
|
||||
},
|
||||
contextMenu: this.inspector.onTextBoxContextMenu,
|
||||
cssProperties: getCssProperties(this.inspector.toolbox)
|
||||
}, event);
|
||||
},
|
||||
|
||||
/**
|
||||
* Shows the box-model highlighter on the currently selected element.
|
||||
*
|
||||
* @param {Object} options
|
||||
* Options passed to the highlighter actor.
|
||||
*/
|
||||
onShowBoxModelHighlighter(options = {}) {
|
||||
let toolbox = this.inspector.toolbox;
|
||||
let nodeFront = this.inspector.selection.nodeFront;
|
||||
|
||||
toolbox.highlighterUtils.highlightNodeFront(nodeFront, options);
|
||||
},
|
||||
|
||||
/**
|
||||
* Handler for the inspector sidebar select event. Starts listening for
|
||||
* "grid-layout-changed" if the layout panel is visible. Otherwise, stop
|
||||
* listening for grid layout changes. Finally, refresh the layout view if
|
||||
* it is visible.
|
||||
*/
|
||||
onSidebarSelect() {
|
||||
if (!this.isPanelVisible()) {
|
||||
this.untrackReflows();
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.inspector.selection.isConnected() &&
|
||||
this.inspector.selection.isElementNode()) {
|
||||
this.trackReflows();
|
||||
}
|
||||
|
||||
this.updateBoxModel();
|
||||
},
|
||||
|
||||
};
|
||||
|
||||
module.exports = BoxModel;
|
|
@ -0,0 +1,51 @@
|
|||
/* 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 { addons, createClass, createFactory, PropTypes } =
|
||||
require("devtools/client/shared/vendor/react");
|
||||
const { connect } = require("devtools/client/shared/vendor/react-redux");
|
||||
|
||||
const { LocalizationHelper } = require("devtools/shared/l10n");
|
||||
|
||||
const Accordion =
|
||||
createFactory(require("devtools/client/inspector/layout/components/Accordion"));
|
||||
const BoxModel = createFactory(require("./BoxModel"));
|
||||
|
||||
const Types = require("../types");
|
||||
|
||||
const BOXMODEL_STRINGS_URI = "devtools/client/locales/boxmodel.properties";
|
||||
const BOXMODEL_L10N = new LocalizationHelper(BOXMODEL_STRINGS_URI);
|
||||
|
||||
const BoxModelApp = createClass({
|
||||
|
||||
displayName: "BoxModelApp",
|
||||
|
||||
propTypes: {
|
||||
boxModel: PropTypes.shape(Types.boxModel).isRequired,
|
||||
showBoxModelProperties: PropTypes.bool.isRequired,
|
||||
onHideBoxModelHighlighter: PropTypes.func.isRequired,
|
||||
onShowBoxModelEditor: PropTypes.func.isRequired,
|
||||
onShowBoxModelHighlighter: PropTypes.func.isRequired,
|
||||
},
|
||||
|
||||
mixins: [ addons.PureRenderMixin ],
|
||||
|
||||
render() {
|
||||
return Accordion({
|
||||
items: [
|
||||
{
|
||||
header: BOXMODEL_L10N.getStr("boxmodel.title"),
|
||||
component: BoxModel,
|
||||
componentProps: this.props,
|
||||
opened: true,
|
||||
}
|
||||
]
|
||||
});
|
||||
},
|
||||
|
||||
});
|
||||
|
||||
module.exports = connect(state => state)(BoxModelApp);
|
|
@ -37,7 +37,23 @@ module.exports = createClass({
|
|||
return layout[property] ? parseFloat(layout[property]) : "-";
|
||||
},
|
||||
|
||||
getHeightOrWidthValue(property) {
|
||||
getHeightValue(property) {
|
||||
let { layout } = this.props.boxModel;
|
||||
|
||||
if (property == undefined) {
|
||||
return "-";
|
||||
}
|
||||
|
||||
property -= parseFloat(layout["border-top-width"]) +
|
||||
parseFloat(layout["border-bottom-width"]) +
|
||||
parseFloat(layout["padding-top"]) +
|
||||
parseFloat(layout["padding-bottom"]);
|
||||
property = parseFloat(property.toPrecision(6));
|
||||
|
||||
return property;
|
||||
},
|
||||
|
||||
getWidthValue(property) {
|
||||
let { layout } = this.props.boxModel;
|
||||
|
||||
if (property == undefined) {
|
||||
|
@ -83,7 +99,7 @@ module.exports = createClass({
|
|||
render() {
|
||||
let { boxModel, onShowBoxModelEditor } = this.props;
|
||||
let { layout } = boxModel;
|
||||
let { width, height } = layout;
|
||||
let { height, width } = layout;
|
||||
|
||||
let borderTop = this.getBorderOrPaddingValue("border-top-width");
|
||||
let borderRight = this.getBorderOrPaddingValue("border-right-width");
|
||||
|
@ -100,8 +116,8 @@ module.exports = createClass({
|
|||
let marginBottom = this.getMarginValue("margin-bottom", "bottom");
|
||||
let marginLeft = this.getMarginValue("margin-left", "left");
|
||||
|
||||
width = this.getHeightOrWidthValue(width);
|
||||
height = this.getHeightOrWidthValue(height);
|
||||
height = this.getHeightValue(height);
|
||||
width = this.getWidthValue(width);
|
||||
|
||||
return dom.div(
|
||||
{
|
|
@ -0,0 +1,15 @@
|
|||
# -*- 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/.
|
||||
|
||||
DevToolsModules(
|
||||
'BoxModel.js',
|
||||
'BoxModelApp.js',
|
||||
'BoxModelEditable.js',
|
||||
'BoxModelInfo.js',
|
||||
'BoxModelMain.js',
|
||||
'BoxModelProperties.js',
|
||||
'ComputedProperty.js',
|
||||
)
|
|
@ -0,0 +1,19 @@
|
|||
# -*- 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/.
|
||||
|
||||
DIRS += [
|
||||
'actions',
|
||||
'components',
|
||||
'reducers',
|
||||
'utils',
|
||||
]
|
||||
|
||||
DevToolsModules(
|
||||
'box-model.js',
|
||||
'types.js',
|
||||
)
|
||||
|
||||
BROWSER_CHROME_MANIFESTS += ['test/browser.ini']
|
|
@ -0,0 +1,9 @@
|
|||
# -*- 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/.
|
||||
|
||||
DevToolsModules(
|
||||
'box-model.js',
|
||||
)
|
|
@ -21,9 +21,11 @@ support-files =
|
|||
[browser_boxmodel_editablemodel_stylerules.js]
|
||||
[browser_boxmodel_guides.js]
|
||||
[browser_boxmodel_navigation.js]
|
||||
skip-if = true # Bug 1336198
|
||||
[browser_boxmodel_rotate-labels-on-sides.js]
|
||||
[browser_boxmodel_sync.js]
|
||||
[browser_boxmodel_tooltips.js]
|
||||
skip-if = true # Bug 1336198
|
||||
[browser_boxmodel_update-after-navigation.js]
|
||||
[browser_boxmodel_update-after-reload.js]
|
||||
# [browser_boxmodel_update-in-iframes.js]
|
|
@ -10,118 +10,118 @@
|
|||
// Expected values:
|
||||
var res1 = [
|
||||
{
|
||||
selector: "#old-boxmodel-element-size",
|
||||
selector: ".boxmodel-element-size",
|
||||
value: "160" + "\u00D7" + "160.117"
|
||||
},
|
||||
{
|
||||
selector: ".old-boxmodel-size > span",
|
||||
selector: ".boxmodel-size > span",
|
||||
value: "100" + "\u00D7" + "100.117"
|
||||
},
|
||||
{
|
||||
selector: ".old-boxmodel-margin.old-boxmodel-top > span",
|
||||
selector: ".boxmodel-margin.boxmodel-top > span",
|
||||
value: 30
|
||||
},
|
||||
{
|
||||
selector: ".old-boxmodel-margin.old-boxmodel-left > span",
|
||||
selector: ".boxmodel-margin.boxmodel-left > span",
|
||||
value: "auto"
|
||||
},
|
||||
{
|
||||
selector: ".old-boxmodel-margin.old-boxmodel-bottom > span",
|
||||
selector: ".boxmodel-margin.boxmodel-bottom > span",
|
||||
value: 30
|
||||
},
|
||||
{
|
||||
selector: ".old-boxmodel-margin.old-boxmodel-right > span",
|
||||
selector: ".boxmodel-margin.boxmodel-right > span",
|
||||
value: "auto"
|
||||
},
|
||||
{
|
||||
selector: ".old-boxmodel-padding.old-boxmodel-top > span",
|
||||
selector: ".boxmodel-padding.boxmodel-top > span",
|
||||
value: 20
|
||||
},
|
||||
{
|
||||
selector: ".old-boxmodel-padding.old-boxmodel-left > span",
|
||||
selector: ".boxmodel-padding.boxmodel-left > span",
|
||||
value: 20
|
||||
},
|
||||
{
|
||||
selector: ".old-boxmodel-padding.old-boxmodel-bottom > span",
|
||||
selector: ".boxmodel-padding.boxmodel-bottom > span",
|
||||
value: 20
|
||||
},
|
||||
{
|
||||
selector: ".old-boxmodel-padding.old-boxmodel-right > span",
|
||||
selector: ".boxmodel-padding.boxmodel-right > span",
|
||||
value: 20
|
||||
},
|
||||
{
|
||||
selector: ".old-boxmodel-border.old-boxmodel-top > span",
|
||||
selector: ".boxmodel-border.boxmodel-top > span",
|
||||
value: 10
|
||||
},
|
||||
{
|
||||
selector: ".old-boxmodel-border.old-boxmodel-left > span",
|
||||
selector: ".boxmodel-border.boxmodel-left > span",
|
||||
value: 10
|
||||
},
|
||||
{
|
||||
selector: ".old-boxmodel-border.old-boxmodel-bottom > span",
|
||||
selector: ".boxmodel-border.boxmodel-bottom > span",
|
||||
value: 10
|
||||
},
|
||||
{
|
||||
selector: ".old-boxmodel-border.old-boxmodel-right > span",
|
||||
selector: ".boxmodel-border.boxmodel-right > span",
|
||||
value: 10
|
||||
},
|
||||
];
|
||||
|
||||
var res2 = [
|
||||
{
|
||||
selector: "#old-boxmodel-element-size",
|
||||
selector: ".boxmodel-element-size",
|
||||
value: "190" + "\u00D7" + "210"
|
||||
},
|
||||
{
|
||||
selector: ".old-boxmodel-size > span",
|
||||
selector: ".boxmodel-size > span",
|
||||
value: "100" + "\u00D7" + "150"
|
||||
},
|
||||
{
|
||||
selector: ".old-boxmodel-margin.old-boxmodel-top > span",
|
||||
selector: ".boxmodel-margin.boxmodel-top > span",
|
||||
value: 30
|
||||
},
|
||||
{
|
||||
selector: ".old-boxmodel-margin.old-boxmodel-left > span",
|
||||
selector: ".boxmodel-margin.boxmodel-left > span",
|
||||
value: "auto"
|
||||
},
|
||||
{
|
||||
selector: ".old-boxmodel-margin.old-boxmodel-bottom > span",
|
||||
selector: ".boxmodel-margin.boxmodel-bottom > span",
|
||||
value: 30
|
||||
},
|
||||
{
|
||||
selector: ".old-boxmodel-margin.old-boxmodel-right > span",
|
||||
selector: ".boxmodel-margin.boxmodel-right > span",
|
||||
value: "auto"
|
||||
},
|
||||
{
|
||||
selector: ".old-boxmodel-padding.old-boxmodel-top > span",
|
||||
selector: ".boxmodel-padding.boxmodel-top > span",
|
||||
value: 20
|
||||
},
|
||||
{
|
||||
selector: ".old-boxmodel-padding.old-boxmodel-left > span",
|
||||
selector: ".boxmodel-padding.boxmodel-left > span",
|
||||
value: 20
|
||||
},
|
||||
{
|
||||
selector: ".old-boxmodel-padding.old-boxmodel-bottom > span",
|
||||
selector: ".boxmodel-padding.boxmodel-bottom > span",
|
||||
value: 20
|
||||
},
|
||||
{
|
||||
selector: ".old-boxmodel-padding.old-boxmodel-right > span",
|
||||
selector: ".boxmodel-padding.boxmodel-right > span",
|
||||
value: 50
|
||||
},
|
||||
{
|
||||
selector: ".old-boxmodel-border.old-boxmodel-top > span",
|
||||
selector: ".boxmodel-border.boxmodel-top > span",
|
||||
value: 10
|
||||
},
|
||||
{
|
||||
selector: ".old-boxmodel-border.old-boxmodel-left > span",
|
||||
selector: ".boxmodel-border.boxmodel-left > span",
|
||||
value: 10
|
||||
},
|
||||
{
|
||||
selector: ".old-boxmodel-border.old-boxmodel-bottom > span",
|
||||
selector: ".boxmodel-border.boxmodel-bottom > span",
|
||||
value: 10
|
||||
},
|
||||
{
|
||||
selector: ".old-boxmodel-border.old-boxmodel-right > span",
|
||||
selector: ".boxmodel-border.boxmodel-right > span",
|
||||
value: 10
|
||||
},
|
||||
];
|
||||
|
@ -142,7 +142,7 @@ add_task(function* () {
|
|||
|
||||
function* testInitialValues(inspector, view) {
|
||||
info("Test that the initial values of the box model are correct");
|
||||
let viewdoc = view.doc;
|
||||
let viewdoc = view.document;
|
||||
|
||||
for (let i = 0; i < res1.length; i++) {
|
||||
let elt = viewdoc.querySelector(res1[i].selector);
|
||||
|
@ -153,7 +153,7 @@ function* testInitialValues(inspector, view) {
|
|||
|
||||
function* testChangingValues(inspector, view, testActor) {
|
||||
info("Test that changing the document updates the box model");
|
||||
let viewdoc = view.doc;
|
||||
let viewdoc = view.document;
|
||||
|
||||
let onUpdated = waitForUpdate(inspector);
|
||||
yield testActor.setAttribute("div", "style",
|
|
@ -36,21 +36,21 @@ function* testEditingMargins(inspector, view, testActor) {
|
|||
"Should be no margin-top on the element.");
|
||||
yield selectNode("#div1", inspector);
|
||||
|
||||
let span = view.doc.querySelector(".old-boxmodel-margin.old-boxmodel-top > span");
|
||||
let span = view.document.querySelector(".boxmodel-margin.boxmodel-top > span");
|
||||
is(span.textContent, 5, "Should have the right value in the box model.");
|
||||
|
||||
EventUtils.synthesizeMouseAtCenter(span, {}, view.doc.defaultView);
|
||||
let editor = view.doc.querySelector(".styleinspector-propertyeditor");
|
||||
EventUtils.synthesizeMouseAtCenter(span, {}, view.document.defaultView);
|
||||
let editor = view.document.querySelector(".styleinspector-propertyeditor");
|
||||
ok(editor, "Should have opened the editor.");
|
||||
is(editor.value, "5px", "Should have the right value in the editor.");
|
||||
|
||||
EventUtils.synthesizeKey("3", {}, view.doc.defaultView);
|
||||
EventUtils.synthesizeKey("3", {}, view.document.defaultView);
|
||||
yield waitForUpdate(inspector);
|
||||
|
||||
is((yield getStyle(testActor, "#div1", "margin-top")), "3px",
|
||||
"Should have updated the margin.");
|
||||
|
||||
EventUtils.synthesizeKey("VK_ESCAPE", {}, view.doc.defaultView);
|
||||
EventUtils.synthesizeKey("VK_ESCAPE", {}, view.document.defaultView);
|
||||
yield waitForUpdate(inspector);
|
||||
|
||||
is((yield getStyle(testActor, "#div1", "margin-top")), "",
|
||||
|
@ -66,35 +66,35 @@ function* testKeyBindings(inspector, view, testActor) {
|
|||
"Should be no margin-top on the element.");
|
||||
yield selectNode("#div1", inspector);
|
||||
|
||||
let span = view.doc.querySelector(".old-boxmodel-margin.old-boxmodel-left > span");
|
||||
let span = view.document.querySelector(".boxmodel-margin.boxmodel-left > span");
|
||||
is(span.textContent, 10, "Should have the right value in the box model.");
|
||||
|
||||
EventUtils.synthesizeMouseAtCenter(span, {}, view.doc.defaultView);
|
||||
let editor = view.doc.querySelector(".styleinspector-propertyeditor");
|
||||
EventUtils.synthesizeMouseAtCenter(span, {}, view.document.defaultView);
|
||||
let editor = view.document.querySelector(".styleinspector-propertyeditor");
|
||||
ok(editor, "Should have opened the editor.");
|
||||
is(editor.value, "10px", "Should have the right value in the editor.");
|
||||
|
||||
EventUtils.synthesizeKey("VK_UP", {}, view.doc.defaultView);
|
||||
EventUtils.synthesizeKey("VK_UP", {}, view.document.defaultView);
|
||||
yield waitForUpdate(inspector);
|
||||
|
||||
is(editor.value, "11px", "Should have the right value in the editor.");
|
||||
is((yield getStyle(testActor, "#div1", "margin-left")), "11px",
|
||||
"Should have updated the margin.");
|
||||
|
||||
EventUtils.synthesizeKey("VK_DOWN", {}, view.doc.defaultView);
|
||||
EventUtils.synthesizeKey("VK_DOWN", {}, view.document.defaultView);
|
||||
yield waitForUpdate(inspector);
|
||||
|
||||
is(editor.value, "10px", "Should have the right value in the editor.");
|
||||
is((yield getStyle(testActor, "#div1", "margin-left")), "10px",
|
||||
"Should have updated the margin.");
|
||||
|
||||
EventUtils.synthesizeKey("VK_UP", { shiftKey: true }, view.doc.defaultView);
|
||||
EventUtils.synthesizeKey("VK_UP", { shiftKey: true }, view.document.defaultView);
|
||||
yield waitForUpdate(inspector);
|
||||
|
||||
is(editor.value, "20px", "Should have the right value in the editor.");
|
||||
is((yield getStyle(testActor, "#div1", "margin-left")), "20px",
|
||||
"Should have updated the margin.");
|
||||
EventUtils.synthesizeKey("VK_RETURN", {}, view.doc.defaultView);
|
||||
EventUtils.synthesizeKey("VK_RETURN", {}, view.document.defaultView);
|
||||
|
||||
is((yield getStyle(testActor, "#div1", "margin-left")), "20px",
|
||||
"Should be the right margin-top on the element.");
|
||||
|
@ -109,22 +109,22 @@ function* testEscapeToUndo(inspector, view, testActor) {
|
|||
"Should be the right margin-top on the element.");
|
||||
yield selectNode("#div1", inspector);
|
||||
|
||||
let span = view.doc.querySelector(".old-boxmodel-margin.old-boxmodel-left > span");
|
||||
let span = view.document.querySelector(".boxmodel-margin.boxmodel-left > span");
|
||||
is(span.textContent, 20, "Should have the right value in the box model.");
|
||||
|
||||
EventUtils.synthesizeMouseAtCenter(span, {}, view.doc.defaultView);
|
||||
let editor = view.doc.querySelector(".styleinspector-propertyeditor");
|
||||
EventUtils.synthesizeMouseAtCenter(span, {}, view.document.defaultView);
|
||||
let editor = view.document.querySelector(".styleinspector-propertyeditor");
|
||||
ok(editor, "Should have opened the editor.");
|
||||
is(editor.value, "20px", "Should have the right value in the editor.");
|
||||
|
||||
EventUtils.synthesizeKey("VK_DELETE", {}, view.doc.defaultView);
|
||||
EventUtils.synthesizeKey("VK_DELETE", {}, view.document.defaultView);
|
||||
yield waitForUpdate(inspector);
|
||||
|
||||
is(editor.value, "", "Should have the right value in the editor.");
|
||||
is((yield getStyle(testActor, "#div1", "margin-left")), "",
|
||||
"Should have updated the margin.");
|
||||
|
||||
EventUtils.synthesizeKey("VK_ESCAPE", {}, view.doc.defaultView);
|
||||
EventUtils.synthesizeKey("VK_ESCAPE", {}, view.document.defaultView);
|
||||
yield waitForUpdate(inspector);
|
||||
|
||||
is((yield getStyle(testActor, "#div1", "margin-left")), "20px",
|
||||
|
@ -140,22 +140,22 @@ function* testDeletingValue(inspector, view, testActor) {
|
|||
|
||||
yield selectNode("#div1", inspector);
|
||||
|
||||
let span = view.doc.querySelector(".old-boxmodel-margin.old-boxmodel-right > span");
|
||||
let span = view.document.querySelector(".boxmodel-margin.boxmodel-right > span");
|
||||
is(span.textContent, 15, "Should have the right value in the box model.");
|
||||
|
||||
EventUtils.synthesizeMouseAtCenter(span, {}, view.doc.defaultView);
|
||||
let editor = view.doc.querySelector(".styleinspector-propertyeditor");
|
||||
EventUtils.synthesizeMouseAtCenter(span, {}, view.document.defaultView);
|
||||
let editor = view.document.querySelector(".styleinspector-propertyeditor");
|
||||
ok(editor, "Should have opened the editor.");
|
||||
is(editor.value, "15px", "Should have the right value in the editor.");
|
||||
|
||||
EventUtils.synthesizeKey("VK_DELETE", {}, view.doc.defaultView);
|
||||
EventUtils.synthesizeKey("VK_DELETE", {}, view.document.defaultView);
|
||||
yield waitForUpdate(inspector);
|
||||
|
||||
is(editor.value, "", "Should have the right value in the editor.");
|
||||
is((yield getStyle(testActor, "#div1", "margin-right")), "",
|
||||
"Should have updated the margin.");
|
||||
|
||||
EventUtils.synthesizeKey("VK_RETURN", {}, view.doc.defaultView);
|
||||
EventUtils.synthesizeKey("VK_RETURN", {}, view.document.defaultView);
|
||||
|
||||
is((yield getStyle(testActor, "#div1", "margin-right")), "",
|
||||
"Should be the right margin-top on the element.");
|
||||
|
@ -167,26 +167,26 @@ function* testRefocusingOnClick(inspector, view, testActor) {
|
|||
|
||||
yield selectNode("#div4", inspector);
|
||||
|
||||
let span = view.doc.querySelector(".old-boxmodel-margin.old-boxmodel-top > span");
|
||||
let span = view.document.querySelector(".boxmodel-margin.boxmodel-top > span");
|
||||
is(span.textContent, 1, "Should have the right value in the box model.");
|
||||
|
||||
EventUtils.synthesizeMouseAtCenter(span, {}, view.doc.defaultView);
|
||||
let editor = view.doc.querySelector(".styleinspector-propertyeditor");
|
||||
EventUtils.synthesizeMouseAtCenter(span, {}, view.document.defaultView);
|
||||
let editor = view.document.querySelector(".styleinspector-propertyeditor");
|
||||
ok(editor, "Should have opened the editor.");
|
||||
|
||||
info("Click in the already opened editor input");
|
||||
EventUtils.synthesizeMouseAtCenter(editor, {}, view.doc.defaultView);
|
||||
is(editor, view.doc.activeElement,
|
||||
EventUtils.synthesizeMouseAtCenter(editor, {}, view.document.defaultView);
|
||||
is(editor, view.document.activeElement,
|
||||
"Inplace editor input should still have focus.");
|
||||
|
||||
info("Check the input can still be used as expected");
|
||||
EventUtils.synthesizeKey("VK_UP", {}, view.doc.defaultView);
|
||||
EventUtils.synthesizeKey("VK_UP", {}, view.document.defaultView);
|
||||
yield waitForUpdate(inspector);
|
||||
|
||||
is(editor.value, "2px", "Should have the right value in the editor.");
|
||||
is((yield getStyle(testActor, "#div4", "margin-top")), "2px",
|
||||
"Should have updated the margin.");
|
||||
EventUtils.synthesizeKey("VK_RETURN", {}, view.doc.defaultView);
|
||||
EventUtils.synthesizeKey("VK_RETURN", {}, view.document.defaultView);
|
||||
|
||||
is((yield getStyle(testActor, "#div4", "margin-top")), "2px",
|
||||
"Should be the right margin-top on the element.");
|
|
@ -32,22 +32,22 @@ function* testEditing(inspector, view, testActor) {
|
|||
|
||||
yield selectNode("#div1", inspector);
|
||||
|
||||
let span = view.doc.querySelector(".old-boxmodel-padding.old-boxmodel-bottom > span");
|
||||
let span = view.document.querySelector(".boxmodel-padding.boxmodel-bottom > span");
|
||||
is(span.textContent, 5, "Should have the right value in the box model.");
|
||||
|
||||
EventUtils.synthesizeMouseAtCenter(span, {}, view.doc.defaultView);
|
||||
let editor = view.doc.querySelector(".styleinspector-propertyeditor");
|
||||
EventUtils.synthesizeMouseAtCenter(span, {}, view.document.defaultView);
|
||||
let editor = view.document.querySelector(".styleinspector-propertyeditor");
|
||||
ok(editor, "Should have opened the editor.");
|
||||
is(editor.value, "5px", "Should have the right value in the editor.");
|
||||
|
||||
EventUtils.synthesizeKey("7", {}, view.doc.defaultView);
|
||||
EventUtils.synthesizeKey("7", {}, view.document.defaultView);
|
||||
yield waitForUpdate(inspector);
|
||||
|
||||
is(editor.value, "7", "Should have the right value in the editor.");
|
||||
is((yield getStyle(testActor, "#div1", "padding-bottom")), "7px",
|
||||
"Should have updated the padding");
|
||||
|
||||
EventUtils.synthesizeKey("VK_RETURN", {}, view.doc.defaultView);
|
||||
EventUtils.synthesizeKey("VK_RETURN", {}, view.document.defaultView);
|
||||
|
||||
is((yield getStyle(testActor, "#div1", "padding-bottom")), "7px",
|
||||
"Should be the right padding.");
|
||||
|
@ -63,22 +63,22 @@ function* testEditingAndCanceling(inspector, view, testActor) {
|
|||
|
||||
yield selectNode("#div1", inspector);
|
||||
|
||||
let span = view.doc.querySelector(".old-boxmodel-padding.old-boxmodel-left > span");
|
||||
let span = view.document.querySelector(".boxmodel-padding.boxmodel-left > span");
|
||||
is(span.textContent, 5, "Should have the right value in the box model.");
|
||||
|
||||
EventUtils.synthesizeMouseAtCenter(span, {}, view.doc.defaultView);
|
||||
let editor = view.doc.querySelector(".styleinspector-propertyeditor");
|
||||
EventUtils.synthesizeMouseAtCenter(span, {}, view.document.defaultView);
|
||||
let editor = view.document.querySelector(".styleinspector-propertyeditor");
|
||||
ok(editor, "Should have opened the editor.");
|
||||
is(editor.value, "5px", "Should have the right value in the editor.");
|
||||
|
||||
EventUtils.synthesizeKey("8", {}, view.doc.defaultView);
|
||||
EventUtils.synthesizeKey("8", {}, view.document.defaultView);
|
||||
yield waitForUpdate(inspector);
|
||||
|
||||
is(editor.value, "8", "Should have the right value in the editor.");
|
||||
is((yield getStyle(testActor, "#div1", "padding-left")), "8px",
|
||||
"Should have updated the padding");
|
||||
|
||||
EventUtils.synthesizeKey("VK_ESCAPE", {}, view.doc.defaultView);
|
||||
EventUtils.synthesizeKey("VK_ESCAPE", {}, view.document.defaultView);
|
||||
yield waitForUpdate(inspector);
|
||||
|
||||
is((yield getStyle(testActor, "#div1", "padding-left")), "5px",
|
||||
|
@ -91,22 +91,22 @@ function* testDeleting(inspector, view, testActor) {
|
|||
|
||||
yield selectNode("#div1", inspector);
|
||||
|
||||
let span = view.doc.querySelector(".old-boxmodel-padding.old-boxmodel-left > span");
|
||||
let span = view.document.querySelector(".boxmodel-padding.boxmodel-left > span");
|
||||
is(span.textContent, 5, "Should have the right value in the box model.");
|
||||
|
||||
EventUtils.synthesizeMouseAtCenter(span, {}, view.doc.defaultView);
|
||||
let editor = view.doc.querySelector(".styleinspector-propertyeditor");
|
||||
EventUtils.synthesizeMouseAtCenter(span, {}, view.document.defaultView);
|
||||
let editor = view.document.querySelector(".styleinspector-propertyeditor");
|
||||
ok(editor, "Should have opened the editor.");
|
||||
is(editor.value, "5px", "Should have the right value in the editor.");
|
||||
|
||||
EventUtils.synthesizeKey("VK_DELETE", {}, view.doc.defaultView);
|
||||
EventUtils.synthesizeKey("VK_DELETE", {}, view.document.defaultView);
|
||||
yield waitForUpdate(inspector);
|
||||
|
||||
is(editor.value, "", "Should have the right value in the editor.");
|
||||
is((yield getStyle(testActor, "#div1", "padding-left")), "",
|
||||
"Should have updated the padding");
|
||||
|
||||
EventUtils.synthesizeKey("VK_RETURN", {}, view.doc.defaultView);
|
||||
EventUtils.synthesizeKey("VK_RETURN", {}, view.document.defaultView);
|
||||
|
||||
is((yield getStyle(testActor, "#div1", "padding-left")), "",
|
||||
"Should be the right padding.");
|
||||
|
@ -122,22 +122,22 @@ function* testDeletingAndCanceling(inspector, view, testActor) {
|
|||
|
||||
yield selectNode("#div1", inspector);
|
||||
|
||||
let span = view.doc.querySelector(".old-boxmodel-padding.old-boxmodel-left > span");
|
||||
let span = view.document.querySelector(".boxmodel-padding.boxmodel-left > span");
|
||||
is(span.textContent, 5, "Should have the right value in the box model.");
|
||||
|
||||
EventUtils.synthesizeMouseAtCenter(span, {}, view.doc.defaultView);
|
||||
let editor = view.doc.querySelector(".styleinspector-propertyeditor");
|
||||
EventUtils.synthesizeMouseAtCenter(span, {}, view.document.defaultView);
|
||||
let editor = view.document.querySelector(".styleinspector-propertyeditor");
|
||||
ok(editor, "Should have opened the editor.");
|
||||
is(editor.value, "5px", "Should have the right value in the editor.");
|
||||
|
||||
EventUtils.synthesizeKey("VK_DELETE", {}, view.doc.defaultView);
|
||||
EventUtils.synthesizeKey("VK_DELETE", {}, view.document.defaultView);
|
||||
yield waitForUpdate(inspector);
|
||||
|
||||
is(editor.value, "", "Should have the right value in the editor.");
|
||||
is((yield getStyle(testActor, "#div1", "padding-left")), "",
|
||||
"Should have updated the padding");
|
||||
|
||||
EventUtils.synthesizeKey("VK_ESCAPE", {}, view.doc.defaultView);
|
||||
EventUtils.synthesizeKey("VK_ESCAPE", {}, view.document.defaultView);
|
||||
yield waitForUpdate(inspector);
|
||||
|
||||
is((yield getStyle(testActor, "#div1", "padding-left")), "5px",
|
|
@ -30,45 +30,45 @@ add_task(function* () {
|
|||
|
||||
function* testClickingOutsideEditor(view) {
|
||||
info("Test that clicking outside the editor blurs it");
|
||||
let span = view.doc.querySelector(".old-boxmodel-margin.old-boxmodel-top > span");
|
||||
let span = view.document.querySelector(".boxmodel-margin.boxmodel-top > span");
|
||||
is(span.textContent, 10, "Should have the right value in the box model.");
|
||||
|
||||
EventUtils.synthesizeMouseAtCenter(span, {}, view.doc.defaultView);
|
||||
let editor = view.doc.querySelector(".styleinspector-propertyeditor");
|
||||
EventUtils.synthesizeMouseAtCenter(span, {}, view.document.defaultView);
|
||||
let editor = view.document.querySelector(".styleinspector-propertyeditor");
|
||||
ok(editor, "Should have opened the editor.");
|
||||
|
||||
info("Click next to the opened editor input.");
|
||||
let onBlur = once(editor, "blur");
|
||||
let rect = editor.getBoundingClientRect();
|
||||
EventUtils.synthesizeMouse(editor, rect.width + 10, rect.height / 2, {},
|
||||
view.doc.defaultView);
|
||||
view.document.defaultView);
|
||||
yield onBlur;
|
||||
|
||||
is(view.doc.querySelector(".styleinspector-propertyeditor"), null,
|
||||
is(view.document.querySelector(".styleinspector-propertyeditor"), null,
|
||||
"Inplace editor has been removed.");
|
||||
}
|
||||
|
||||
function* testClickingBelowContainer(view) {
|
||||
info("Test that clicking below the box-model container blurs it");
|
||||
let span = view.doc.querySelector(".old-boxmodel-margin.old-boxmodel-top > span");
|
||||
let span = view.document.querySelector(".boxmodel-margin.boxmodel-top > span");
|
||||
is(span.textContent, 10, "Should have the right value in the box model.");
|
||||
|
||||
info("Test that clicking below the old-boxmodel-container blurs the opened editor");
|
||||
EventUtils.synthesizeMouseAtCenter(span, {}, view.doc.defaultView);
|
||||
let editor = view.doc.querySelector(".styleinspector-propertyeditor");
|
||||
info("Test that clicking below the boxmodel-container blurs the opened editor");
|
||||
EventUtils.synthesizeMouseAtCenter(span, {}, view.document.defaultView);
|
||||
let editor = view.document.querySelector(".styleinspector-propertyeditor");
|
||||
ok(editor, "Should have opened the editor.");
|
||||
|
||||
let onBlur = once(editor, "blur");
|
||||
let container = view.doc.querySelector("#old-boxmodel-container");
|
||||
let container = view.document.querySelector(".boxmodel-container");
|
||||
// Using getBoxQuads here because getBoundingClientRect (and therefore synthesizeMouse)
|
||||
// use an erroneous height of ~50px for the boxmodel-container.
|
||||
let bounds = container.getBoxQuads({relativeTo: view.doc})[0].bounds;
|
||||
EventUtils.synthesizeMouseAtPoint(
|
||||
bounds.left + 10,
|
||||
bounds.top + bounds.height + 10,
|
||||
{}, view.doc.defaultView);
|
||||
{}, view.document.defaultView);
|
||||
yield onBlur;
|
||||
|
||||
is(view.doc.querySelector(".styleinspector-propertyeditor"), null,
|
||||
is(view.document.querySelector(".styleinspector-propertyeditor"), null,
|
||||
"Inplace editor has been removed.");
|
||||
}
|
|
@ -24,15 +24,15 @@ add_task(function* () {
|
|||
"Should have the right border");
|
||||
yield selectNode("#div1", inspector);
|
||||
|
||||
let span = view.doc.querySelector(".old-boxmodel-border.old-boxmodel-top > span");
|
||||
let span = view.document.querySelector(".boxmodel-border.boxmodel-top > span");
|
||||
is(span.textContent, 0, "Should have the right value in the box model.");
|
||||
|
||||
EventUtils.synthesizeMouseAtCenter(span, {}, view.doc.defaultView);
|
||||
let editor = view.doc.querySelector(".styleinspector-propertyeditor");
|
||||
EventUtils.synthesizeMouseAtCenter(span, {}, view.document.defaultView);
|
||||
let editor = view.document.querySelector(".styleinspector-propertyeditor");
|
||||
ok(editor, "Should have opened the editor.");
|
||||
is(editor.value, "0", "Should have the right value in the editor.");
|
||||
|
||||
EventUtils.synthesizeKey("1", {}, view.doc.defaultView);
|
||||
EventUtils.synthesizeKey("1", {}, view.document.defaultView);
|
||||
yield waitForUpdate(inspector);
|
||||
|
||||
is(editor.value, "1", "Should have the right value in the editor.");
|
||||
|
@ -41,7 +41,7 @@ add_task(function* () {
|
|||
is((yield getStyle(testActor, "#div1", "border-top-style")), "solid",
|
||||
"Should have the right border");
|
||||
|
||||
EventUtils.synthesizeKey("VK_ESCAPE", {}, view.doc.defaultView);
|
||||
EventUtils.synthesizeKey("VK_ESCAPE", {}, view.document.defaultView);
|
||||
yield waitForUpdate(inspector);
|
||||
|
||||
is((yield getStyle(testActor, "#div1", "border-top-width")), "",
|
|
@ -31,30 +31,30 @@ function* testUnits(inspector, view, testActor) {
|
|||
"Should have the right padding");
|
||||
yield selectNode("#div1", inspector);
|
||||
|
||||
let span = view.doc.querySelector(".old-boxmodel-padding.old-boxmodel-top > span");
|
||||
let span = view.document.querySelector(".boxmodel-padding.boxmodel-top > span");
|
||||
is(span.textContent, 3, "Should have the right value in the box model.");
|
||||
|
||||
EventUtils.synthesizeMouseAtCenter(span, {}, view.doc.defaultView);
|
||||
let editor = view.doc.querySelector(".styleinspector-propertyeditor");
|
||||
EventUtils.synthesizeMouseAtCenter(span, {}, view.document.defaultView);
|
||||
let editor = view.document.querySelector(".styleinspector-propertyeditor");
|
||||
ok(editor, "Should have opened the editor.");
|
||||
is(editor.value, "3px", "Should have the right value in the editor.");
|
||||
|
||||
EventUtils.synthesizeKey("1", {}, view.doc.defaultView);
|
||||
EventUtils.synthesizeKey("1", {}, view.document.defaultView);
|
||||
yield waitForUpdate(inspector);
|
||||
EventUtils.synthesizeKey("e", {}, view.doc.defaultView);
|
||||
EventUtils.synthesizeKey("e", {}, view.document.defaultView);
|
||||
yield waitForUpdate(inspector);
|
||||
|
||||
is((yield getStyle(testActor, "#div1", "padding-top")), "",
|
||||
"An invalid value is handled cleanly");
|
||||
|
||||
EventUtils.synthesizeKey("m", {}, view.doc.defaultView);
|
||||
EventUtils.synthesizeKey("m", {}, view.document.defaultView);
|
||||
yield waitForUpdate(inspector);
|
||||
|
||||
is(editor.value, "1em", "Should have the right value in the editor.");
|
||||
is((yield getStyle(testActor, "#div1", "padding-top")),
|
||||
"1em", "Should have updated the padding.");
|
||||
|
||||
EventUtils.synthesizeKey("VK_RETURN", {}, view.doc.defaultView);
|
||||
EventUtils.synthesizeKey("VK_RETURN", {}, view.document.defaultView);
|
||||
|
||||
is((yield getStyle(testActor, "#div1", "padding-top")), "1em",
|
||||
"Should be the right padding.");
|
||||
|
@ -68,22 +68,22 @@ function* testValueComesFromStyleRule(inspector, view, testActor) {
|
|||
"Should have the right border-bottom-width");
|
||||
yield selectNode("#div2", inspector);
|
||||
|
||||
let span = view.doc.querySelector(".old-boxmodel-border.old-boxmodel-bottom > span");
|
||||
let span = view.document.querySelector(".boxmodel-border.boxmodel-bottom > span");
|
||||
is(span.textContent, 16, "Should have the right value in the box model.");
|
||||
|
||||
EventUtils.synthesizeMouseAtCenter(span, {}, view.doc.defaultView);
|
||||
let editor = view.doc.querySelector(".styleinspector-propertyeditor");
|
||||
EventUtils.synthesizeMouseAtCenter(span, {}, view.document.defaultView);
|
||||
let editor = view.document.querySelector(".styleinspector-propertyeditor");
|
||||
ok(editor, "Should have opened the editor.");
|
||||
is(editor.value, "1em", "Should have the right value in the editor.");
|
||||
|
||||
EventUtils.synthesizeKey("0", {}, view.doc.defaultView);
|
||||
EventUtils.synthesizeKey("0", {}, view.document.defaultView);
|
||||
yield waitForUpdate(inspector);
|
||||
|
||||
is(editor.value, "0", "Should have the right value in the editor.");
|
||||
is((yield getStyle(testActor, "#div2", "border-bottom-width")), "0px",
|
||||
"Should have updated the border.");
|
||||
|
||||
EventUtils.synthesizeKey("VK_RETURN", {}, view.doc.defaultView);
|
||||
EventUtils.synthesizeKey("VK_RETURN", {}, view.document.defaultView);
|
||||
|
||||
is((yield getStyle(testActor, "#div2", "border-bottom-width")), "0px",
|
||||
"Should be the right border-bottom-width.");
|
||||
|
@ -97,15 +97,15 @@ function* testShorthandsAreParsed(inspector, view, testActor) {
|
|||
"Should have the right padding");
|
||||
yield selectNode("#div3", inspector);
|
||||
|
||||
let span = view.doc.querySelector(".old-boxmodel-padding.old-boxmodel-right > span");
|
||||
let span = view.document.querySelector(".boxmodel-padding.boxmodel-right > span");
|
||||
is(span.textContent, 32, "Should have the right value in the box model.");
|
||||
|
||||
EventUtils.synthesizeMouseAtCenter(span, {}, view.doc.defaultView);
|
||||
let editor = view.doc.querySelector(".styleinspector-propertyeditor");
|
||||
EventUtils.synthesizeMouseAtCenter(span, {}, view.document.defaultView);
|
||||
let editor = view.document.querySelector(".styleinspector-propertyeditor");
|
||||
ok(editor, "Should have opened the editor.");
|
||||
is(editor.value, "2em", "Should have the right value in the editor.");
|
||||
|
||||
EventUtils.synthesizeKey("VK_RETURN", {}, view.doc.defaultView);
|
||||
EventUtils.synthesizeKey("VK_RETURN", {}, view.document.defaultView);
|
||||
|
||||
is((yield getStyle(testActor, "#div3", "padding-right")), "",
|
||||
"Should be the right padding.");
|
|
@ -28,16 +28,16 @@ add_task(function* () {
|
|||
highlighterOptions = options;
|
||||
};
|
||||
|
||||
let elt = view.doc.getElementById("old-boxmodel-margins");
|
||||
let elt = view.document.querySelector(".boxmodel-margins");
|
||||
yield testGuideOnLayoutHover(elt, "margin", inspector, view);
|
||||
|
||||
elt = view.doc.getElementById("old-boxmodel-borders");
|
||||
elt = view.document.querySelector(".boxmodel-borders");
|
||||
yield testGuideOnLayoutHover(elt, "border", inspector, view);
|
||||
|
||||
elt = view.doc.getElementById("old-boxmodel-padding");
|
||||
elt = view.document.querySelector(".boxmodel-paddings");
|
||||
yield testGuideOnLayoutHover(elt, "padding", inspector, view);
|
||||
|
||||
elt = view.doc.getElementById("old-boxmodel-content");
|
||||
elt = view.document.querySelector(".boxmodel-content");
|
||||
yield testGuideOnLayoutHover(elt, "content", inspector, view);
|
||||
});
|
||||
|
|
@ -29,50 +29,50 @@ add_task(function* () {
|
|||
function* testInitialFocus(inspector, view) {
|
||||
info("Test that the focus is on margin layout.");
|
||||
let viewdoc = view.doc;
|
||||
let boxmodel = viewdoc.getElementById("old-boxmodel-wrapper");
|
||||
let boxmodel = viewdoc.getElementById("boxmodel-wrapper");
|
||||
boxmodel.focus();
|
||||
EventUtils.synthesizeKey("VK_RETURN", {});
|
||||
|
||||
is(boxmodel.getAttribute("aria-activedescendant"), "old-boxmodel-margins",
|
||||
is(boxmodel.getAttribute("aria-activedescendant"), "boxmodel-margins",
|
||||
"Should be set to the margin layout.");
|
||||
}
|
||||
|
||||
function* testChangingLevels(inspector, view) {
|
||||
info("Test that using arrow keys updates level.");
|
||||
let viewdoc = view.doc;
|
||||
let boxmodel = viewdoc.getElementById("old-boxmodel-wrapper");
|
||||
let boxmodel = viewdoc.getElementById("boxmodel-wrapper");
|
||||
boxmodel.focus();
|
||||
EventUtils.synthesizeKey("VK_RETURN", {});
|
||||
EventUtils.synthesizeKey("VK_ESCAPE", {});
|
||||
|
||||
EventUtils.synthesizeKey("VK_DOWN", {});
|
||||
is(boxmodel.getAttribute("aria-activedescendant"), "old-boxmodel-borders",
|
||||
is(boxmodel.getAttribute("aria-activedescendant"), "boxmodel-borders",
|
||||
"Should be set to the border layout.");
|
||||
|
||||
EventUtils.synthesizeKey("VK_DOWN", {});
|
||||
is(boxmodel.getAttribute("aria-activedescendant"), "old-boxmodel-padding",
|
||||
is(boxmodel.getAttribute("aria-activedescendant"), "boxmodel-padding",
|
||||
"Should be set to the padding layout.");
|
||||
|
||||
EventUtils.synthesizeKey("VK_UP", {});
|
||||
is(boxmodel.getAttribute("aria-activedescendant"), "old-boxmodel-borders",
|
||||
is(boxmodel.getAttribute("aria-activedescendant"), "boxmodel-borders",
|
||||
"Should be set to the border layout.");
|
||||
|
||||
EventUtils.synthesizeKey("VK_UP", {});
|
||||
is(boxmodel.getAttribute("aria-activedescendant"), "old-boxmodel-margins",
|
||||
is(boxmodel.getAttribute("aria-activedescendant"), "boxmodel-margins",
|
||||
"Should be set to the margin layout.");
|
||||
}
|
||||
|
||||
function* testTabbingWrapAround(inspector, view) {
|
||||
info("Test that using arrow keys updates level.");
|
||||
let viewdoc = view.doc;
|
||||
let boxmodel = viewdoc.getElementById("old-boxmodel-wrapper");
|
||||
let boxmodel = viewdoc.getElementById("boxmodel-wrapper");
|
||||
boxmodel.focus();
|
||||
EventUtils.synthesizeKey("VK_RETURN", {});
|
||||
|
||||
let editLevel = boxmodel.getAttribute("aria-activedescendant");
|
||||
let dataLevel = viewdoc.getElementById(editLevel).getAttribute("data-box");
|
||||
let editBoxes = [...viewdoc.querySelectorAll(
|
||||
`[data-box="${dataLevel}"].old-boxmodel-editable`)];
|
||||
`[data-box="${dataLevel}"].boxmodel-editable`)];
|
||||
|
||||
EventUtils.synthesizeKey("VK_ESCAPE", {});
|
||||
editBoxes[3].focus();
|
||||
|
@ -87,12 +87,12 @@ function* testTabbingWrapAround(inspector, view) {
|
|||
function* testChangingLevelsByClicking(inspector, view) {
|
||||
info("Test that clicking on levels updates level.");
|
||||
let viewdoc = view.doc;
|
||||
let boxmodel = viewdoc.getElementById("old-boxmodel-wrapper");
|
||||
let boxmodel = viewdoc.getElementById("boxmodel-wrapper");
|
||||
boxmodel.focus();
|
||||
|
||||
let marginLayout = viewdoc.getElementById("old-boxmodel-margins");
|
||||
let borderLayout = viewdoc.getElementById("old-boxmodel-borders");
|
||||
let paddingLayout = viewdoc.getElementById("old-boxmodel-padding");
|
||||
let marginLayout = viewdoc.getElementById("boxmodel-margins");
|
||||
let borderLayout = viewdoc.getElementById("boxmodel-borders");
|
||||
let paddingLayout = viewdoc.getElementById("boxmodel-padding");
|
||||
let layouts = [paddingLayout, borderLayout, marginLayout];
|
||||
|
||||
layouts.forEach(layout => {
|
|
@ -0,0 +1,49 @@
|
|||
/* vim: set ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
// Test that longer values are rotated on the side
|
||||
|
||||
const res1 = [
|
||||
{selector: ".boxmodel-margin.boxmodel-top > span", value: 30},
|
||||
{selector: ".boxmodel-margin.boxmodel-left > span", value: "auto"},
|
||||
{selector: ".boxmodel-margin.boxmodel-bottom > span", value: 30},
|
||||
{selector: ".boxmodel-margin.boxmodel-right > span", value: "auto"},
|
||||
{selector: ".boxmodel-padding.boxmodel-top > span", value: 20},
|
||||
{selector: ".boxmodel-padding.boxmodel-left > span", value: 2000000},
|
||||
{selector: ".boxmodel-padding.boxmodel-bottom > span", value: 20},
|
||||
{selector: ".boxmodel-padding.boxmodel-right > span", value: 20},
|
||||
{selector: ".boxmodel-border.boxmodel-top > span", value: 10},
|
||||
{selector: ".boxmodel-border.boxmodel-left > span", value: 10},
|
||||
{selector: ".boxmodel-border.boxmodel-bottom > span", value: 10},
|
||||
{selector: ".boxmodel-border.boxmodel-right > span", value: 10},
|
||||
];
|
||||
|
||||
const TEST_URI = encodeURIComponent([
|
||||
"<style>",
|
||||
"div { border:10px solid black; padding: 20px 20px 20px 2000000px; " +
|
||||
"margin: 30px auto; }",
|
||||
"</style>",
|
||||
"<div></div>"
|
||||
].join(""));
|
||||
const LONG_TEXT_ROTATE_LIMIT = 3;
|
||||
|
||||
add_task(function* () {
|
||||
yield addTab("data:text/html," + TEST_URI);
|
||||
let {inspector, view} = yield openBoxModelView();
|
||||
yield selectNode("div", inspector);
|
||||
|
||||
for (let i = 0; i < res1.length; i++) {
|
||||
let elt = view.document.querySelector(res1[i].selector);
|
||||
let isLong = elt.textContent.length > LONG_TEXT_ROTATE_LIMIT;
|
||||
let classList = elt.parentNode.classList;
|
||||
let canBeRotated = classList.contains("boxmodel-left") ||
|
||||
classList.contains("boxmodel-right");
|
||||
let isRotated = classList.contains("boxmodel-rotate");
|
||||
|
||||
is(canBeRotated && isLong,
|
||||
isRotated, res1[i].selector + " correctly rotated.");
|
||||
}
|
||||
});
|
|
@ -17,14 +17,14 @@ add_task(function* () {
|
|||
yield selectNode("p", inspector);
|
||||
|
||||
info("Modify padding-bottom in box model view");
|
||||
let span = view.doc.querySelector(".old-boxmodel-padding.old-boxmodel-bottom > span");
|
||||
EventUtils.synthesizeMouseAtCenter(span, {}, view.doc.defaultView);
|
||||
let editor = view.doc.querySelector(".styleinspector-propertyeditor");
|
||||
let span = view.document.querySelector(".boxmodel-padding.boxmodel-bottom > span");
|
||||
EventUtils.synthesizeMouseAtCenter(span, {}, view.document.defaultView);
|
||||
let editor = view.document.querySelector(".styleinspector-propertyeditor");
|
||||
|
||||
EventUtils.synthesizeKey("7", {}, view.doc.defaultView);
|
||||
EventUtils.synthesizeKey("7", {}, view.document.defaultView);
|
||||
yield waitForUpdate(inspector);
|
||||
is(editor.value, "7", "Should have the right value in the editor.");
|
||||
EventUtils.synthesizeKey("VK_RETURN", {}, view.doc.defaultView);
|
||||
EventUtils.synthesizeKey("VK_RETURN", {}, view.document.defaultView);
|
||||
|
||||
let onRuleViewRefreshed = once(inspector, "rule-view-refreshed");
|
||||
let onRuleViewSelected = once(inspector.sidebar, "ruleview-selected");
|
|
@ -76,24 +76,24 @@ add_task(function* () {
|
|||
|
||||
info("Checking the regions tooltips");
|
||||
|
||||
ok(view.doc.querySelector("#old-boxmodel-margins").hasAttribute("title"),
|
||||
ok(view.document.querySelector(".boxmodel-margins").hasAttribute("title"),
|
||||
"The margin region has a tooltip");
|
||||
is(view.doc.querySelector("#old-boxmodel-margins").getAttribute("title"), "margin",
|
||||
is(view.document.querySelector(".boxmodel-margins").getAttribute("title"), "margin",
|
||||
"The margin region has the correct tooltip content");
|
||||
|
||||
ok(view.doc.querySelector("#old-boxmodel-borders").hasAttribute("title"),
|
||||
ok(view.document.querySelector(".boxmodel-borders").hasAttribute("title"),
|
||||
"The border region has a tooltip");
|
||||
is(view.doc.querySelector("#old-boxmodel-borders").getAttribute("title"), "border",
|
||||
is(view.document.querySelector(".boxmodel-borders").getAttribute("title"), "border",
|
||||
"The border region has the correct tooltip content");
|
||||
|
||||
ok(view.doc.querySelector("#old-boxmodel-padding").hasAttribute("title"),
|
||||
ok(view.document.querySelector(".boxmodel-paddings").hasAttribute("title"),
|
||||
"The padding region has a tooltip");
|
||||
is(view.doc.querySelector("#old-boxmodel-padding").getAttribute("title"), "padding",
|
||||
is(view.document.querySelector(".boxmodel-paddings").getAttribute("title"), "padding",
|
||||
"The padding region has the correct tooltip content");
|
||||
|
||||
ok(view.doc.querySelector("#old-boxmodel-content").hasAttribute("title"),
|
||||
ok(view.document.querySelector(".boxmodel-content").hasAttribute("title"),
|
||||
"The content region has a tooltip");
|
||||
is(view.doc.querySelector("#old-boxmodel-content").getAttribute("title"), "content",
|
||||
is(view.document.querySelector(".boxmodel-content").getAttribute("title"), "content",
|
||||
"The content region has the correct tooltip content");
|
||||
|
||||
for (let {selector, values} of VALUES_TEST_DATA) {
|
||||
|
@ -108,7 +108,7 @@ add_task(function* () {
|
|||
|
||||
let name = view.map[key].property;
|
||||
let expectedTooltipData = values.find(o => o.name === name);
|
||||
let el = view.doc.querySelector(view.map[key].selector);
|
||||
let el = view.document.querySelector(view.map[key].selector);
|
||||
|
||||
ok(el.hasAttribute("title"), "The " + name + " value has a tooltip");
|
||||
|
|
@ -17,14 +17,16 @@ add_task(function* () {
|
|||
yield testFirstPage(inspector, view, testActor);
|
||||
|
||||
info("Navigate to the second page");
|
||||
let onMarkupLoaded = waitForMarkupLoaded(inspector);
|
||||
yield testActor.eval(`content.location.href="${IFRAME2}"`);
|
||||
yield inspector.once("markuploaded");
|
||||
yield onMarkupLoaded;
|
||||
|
||||
yield testSecondPage(inspector, view, testActor);
|
||||
|
||||
info("Go back to the first page");
|
||||
onMarkupLoaded = waitForMarkupLoaded(inspector);
|
||||
yield testActor.eval("content.history.back();");
|
||||
yield inspector.once("markuploaded");
|
||||
yield onMarkupLoaded;
|
||||
|
||||
yield testBackToFirstPage(inspector, view, testActor);
|
||||
});
|
||||
|
@ -32,12 +34,11 @@ add_task(function* () {
|
|||
function* testFirstPage(inspector, view, testActor) {
|
||||
info("Test that the box model view works on the first page");
|
||||
|
||||
info("Selecting the test node");
|
||||
yield selectNode("p", inspector);
|
||||
|
||||
info("Checking that the box model view shows the right value");
|
||||
let paddingElt = view.doc.querySelector(
|
||||
".old-boxmodel-padding.old-boxmodel-top > span");
|
||||
let paddingElt = view.document.querySelector(
|
||||
".boxmodel-padding.boxmodel-top > span");
|
||||
is(paddingElt.textContent, "50");
|
||||
|
||||
info("Listening for box model view changes and modifying the padding");
|
||||
|
@ -53,11 +54,10 @@ function* testFirstPage(inspector, view, testActor) {
|
|||
function* testSecondPage(inspector, view, testActor) {
|
||||
info("Test that the box model view works on the second page");
|
||||
|
||||
info("Selecting the test node");
|
||||
yield selectNode("p", inspector);
|
||||
|
||||
info("Checking that the box model view shows the right value");
|
||||
let sizeElt = view.doc.querySelector(".old-boxmodel-size > span");
|
||||
let sizeElt = view.document.querySelector(".boxmodel-size > span");
|
||||
is(sizeElt.textContent, "100" + "\u00D7" + "100");
|
||||
|
||||
info("Listening for box model view changes and modifying the size");
|
||||
|
@ -73,13 +73,12 @@ function* testSecondPage(inspector, view, testActor) {
|
|||
function* testBackToFirstPage(inspector, view, testActor) {
|
||||
info("Test that the box model view works on the first page after going back");
|
||||
|
||||
info("Selecting the test node");
|
||||
yield selectNode("p", inspector);
|
||||
|
||||
info("Checking that the box model view shows the right value, which is the" +
|
||||
"modified value from step one because of the bfcache");
|
||||
let paddingElt = view.doc.querySelector(
|
||||
".old-boxmodel-padding.old-boxmodel-top > span");
|
||||
let paddingElt = view.document.querySelector(
|
||||
".boxmodel-padding.boxmodel-top > span");
|
||||
is(paddingElt.textContent, "20");
|
||||
|
||||
info("Listening for box model view changes and modifying the padding");
|
|
@ -14,20 +14,20 @@ add_task(function* () {
|
|||
yield assertBoxModelView(inspector, view, testActor);
|
||||
|
||||
info("Reload the page");
|
||||
let onMarkupLoaded = waitForMarkupLoaded(inspector);
|
||||
yield testActor.reload();
|
||||
yield inspector.once("markuploaded");
|
||||
yield onMarkupLoaded;
|
||||
|
||||
info("Test that the box model view works on the reloaded page");
|
||||
yield assertBoxModelView(inspector, view, testActor);
|
||||
});
|
||||
|
||||
function* assertBoxModelView(inspector, view, testActor) {
|
||||
info("Selecting the test node");
|
||||
yield selectNode("p", inspector);
|
||||
|
||||
info("Checking that the box model view shows the right value");
|
||||
let paddingElt = view.doc.querySelector(
|
||||
".old-boxmodel-padding.old-boxmodel-top > span");
|
||||
let paddingElt = view.document.querySelector(
|
||||
".boxmodel-padding.boxmodel-top > span");
|
||||
is(paddingElt.textContent, "50");
|
||||
|
||||
info("Listening for box model view changes and modifying the padding");
|
|
@ -22,7 +22,7 @@ function* testResizingInIframe(inspector, view, testActor) {
|
|||
yield selectNodeInIframe2("div", inspector);
|
||||
|
||||
info("Checking that the box model view shows the right value");
|
||||
let sizeElt = view.doc.querySelector(".old-boxmodel-size > span");
|
||||
let sizeElt = view.document.querySelector(".boxmodel-size > span");
|
||||
is(sizeElt.textContent, "400\u00D7200");
|
||||
|
||||
info("Listening for box model view changes and modifying its size");
|
||||
|
@ -40,14 +40,15 @@ function* testReflowsAfterIframeDeletion(inspector, view, testActor) {
|
|||
"iframe");
|
||||
|
||||
info("Deleting the iframe2");
|
||||
let onInspectorUpdated = inspector.once("inspector-updated");
|
||||
yield removeIframe2(testActor);
|
||||
yield inspector.once("inspector-updated");
|
||||
yield onInspectorUpdated;
|
||||
|
||||
info("Selecting the test node in iframe1");
|
||||
yield selectNodeInIframe1("p", inspector);
|
||||
|
||||
info("Checking that the box model view shows the right value");
|
||||
let sizeElt = view.doc.querySelector(".old-boxmodel-size > span");
|
||||
let sizeElt = view.document.querySelector(".boxmodel-size > span");
|
||||
is(sizeElt.textContent, "100\u00D7100");
|
||||
|
||||
info("Listening for box model view changes and modifying its size");
|
|
@ -19,12 +19,13 @@ registerCleanupFunction(() => {
|
|||
/**
|
||||
* Highlight a node and set the inspector's current selection to the node or
|
||||
* the first match of the given css selector.
|
||||
*
|
||||
* @param {String|NodeFront} selectorOrNodeFront
|
||||
* The selector for the node to be set, or the nodeFront
|
||||
* The selector for the node to be set, or the nodeFront.
|
||||
* @param {InspectorPanel} inspector
|
||||
* The instance of InspectorPanel currently loaded in the toolbox
|
||||
* @return a promise that resolves when the inspector is updated with the new
|
||||
* node
|
||||
* The instance of InspectorPanel currently loaded in the toolbox.
|
||||
* @return {Promise} a promise that resolves when the inspector is updated with the new
|
||||
* node.
|
||||
*/
|
||||
function* selectAndHighlightNode(selectorOrNodeFront, inspector) {
|
||||
info("Highlighting and selecting the node " + selectorOrNodeFront);
|
||||
|
@ -38,8 +39,9 @@ function* selectAndHighlightNode(selectorOrNodeFront, inspector) {
|
|||
/**
|
||||
* Open the toolbox, with the inspector tool visible, and the computed view
|
||||
* sidebar tab selected to display the box model view.
|
||||
* @return a promise that resolves when the inspector is ready and the box model
|
||||
* view is visible and ready
|
||||
*
|
||||
* @return {Promise} a promise that resolves when the inspector is ready and the box model
|
||||
* view is visible and ready.
|
||||
*/
|
||||
function openBoxModelView() {
|
||||
return openInspectorSidebarTab("computedview").then(data => {
|
||||
|
@ -58,7 +60,7 @@ function openBoxModelView() {
|
|||
return {
|
||||
toolbox: data.toolbox,
|
||||
inspector: data.inspector,
|
||||
view: data.inspector.computedview.boxModelView,
|
||||
view: data.inspector.computedview,
|
||||
testActor: data.testActor
|
||||
};
|
||||
});
|
||||
|
@ -66,10 +68,37 @@ function openBoxModelView() {
|
|||
|
||||
/**
|
||||
* Wait for the boxmodel-view-updated event.
|
||||
* @return a promise
|
||||
*
|
||||
* @param {InspectorPanel} inspector
|
||||
* The instance of InspectorPanel currently loaded in the toolbox.
|
||||
* @param {Boolean} waitForSelectionUpdate
|
||||
* Should the boxmodel-view-updated event come from a new selection.
|
||||
* @return {Promise} a promise
|
||||
*/
|
||||
function waitForUpdate(inspector) {
|
||||
return inspector.once("boxmodel-view-updated");
|
||||
function waitForUpdate(inspector, waitForSelectionUpdate) {
|
||||
return new Promise(resolve => {
|
||||
inspector.on("boxmodel-view-updated", function onUpdate(e, reasons) {
|
||||
// Wait for another update event if we are waiting for a selection related event.
|
||||
if (waitForSelectionUpdate && !reasons.includes("new-selection")) {
|
||||
return;
|
||||
}
|
||||
|
||||
inspector.off("boxmodel-view-updated", onUpdate);
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Wait for both boxmode-view-updated and markuploaded events.
|
||||
*
|
||||
* @return {Promise} a promise that resolves when both events have been received.
|
||||
*/
|
||||
function waitForMarkupLoaded(inspector) {
|
||||
return Promise.all([
|
||||
waitForUpdate(inspector),
|
||||
inspector.once("markuploaded"),
|
||||
]);
|
||||
}
|
||||
|
||||
function getStyle(testActor, selector, propertyName) {
|
||||
|
@ -85,3 +114,15 @@ function setStyle(testActor, selector, propertyName, value) {
|
|||
.style.${propertyName} = "${value}";
|
||||
`);
|
||||
}
|
||||
|
||||
/**
|
||||
* The box model doesn't participate in the inspector's update mechanism, so simply
|
||||
* calling the default selectNode isn't enough to guarantee that the box model view has
|
||||
* finished updating. We also need to wait for the "boxmodel-view-updated" event.
|
||||
*/
|
||||
var _selectNode = selectNode;
|
||||
selectNode = function* (node, inspector, reason) {
|
||||
let onUpdate = waitForUpdate(inspector, true);
|
||||
yield _selectNode(node, inspector, reason);
|
||||
yield onUpdate;
|
||||
};
|
|
@ -0,0 +1,17 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
"use strict";
|
||||
|
||||
const { PropTypes } = require("devtools/client/shared/vendor/react");
|
||||
|
||||
/**
|
||||
* The box model data for the current selected node.
|
||||
*/
|
||||
exports.boxModel = {
|
||||
|
||||
// The layout information of the current selected node
|
||||
layout: PropTypes.object,
|
||||
|
||||
};
|
|
@ -0,0 +1,9 @@
|
|||
# -*- 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/.
|
||||
|
||||
DevToolsModules(
|
||||
'editing-session.js',
|
||||
)
|
|
@ -1,912 +0,0 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
/**
|
||||
* THIS MODULE IS DEPRECATED.
|
||||
*
|
||||
* To continue any work related to the box model view, see the new react/redux
|
||||
* implementation in devtools/client/inspector/layout/.
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
const {Task} = require("devtools/shared/task");
|
||||
const {InplaceEditor, editableItem} =
|
||||
require("devtools/client/shared/inplace-editor");
|
||||
const {ReflowFront} = require("devtools/shared/fronts/reflow");
|
||||
const {LocalizationHelper} = require("devtools/shared/l10n");
|
||||
const {getCssProperties} = require("devtools/shared/fronts/css-properties");
|
||||
const {KeyCodes} = require("devtools/client/shared/keycodes");
|
||||
const EditingSession = require("devtools/client/inspector/layout/utils/editing-session");
|
||||
|
||||
const STRINGS_URI = "devtools/client/locales/shared.properties";
|
||||
const STRINGS_INSPECTOR = "devtools/shared/locales/styleinspector.properties";
|
||||
const SHARED_L10N = new LocalizationHelper(STRINGS_URI);
|
||||
const INSPECTOR_L10N = new LocalizationHelper(STRINGS_INSPECTOR);
|
||||
const NUMERIC = /^-?[\d\.]+$/;
|
||||
const LONG_TEXT_ROTATE_LIMIT = 3;
|
||||
|
||||
/**
|
||||
* The box model view
|
||||
* @param {InspectorPanel} inspector
|
||||
* An instance of the inspector-panel currently loaded in the toolbox
|
||||
* @param {Document} document
|
||||
* The document that will contain the box model view.
|
||||
*/
|
||||
function BoxModelView(inspector, document) {
|
||||
this.inspector = inspector;
|
||||
this.doc = document;
|
||||
this.wrapper = this.doc.getElementById("old-boxmodel-wrapper");
|
||||
this.container = this.doc.getElementById("old-boxmodel-container");
|
||||
this.expander = this.doc.getElementById("old-boxmodel-expander");
|
||||
this.sizeLabel = this.doc.querySelector(".old-boxmodel-size > span");
|
||||
this.sizeHeadingLabel = this.doc.getElementById("old-boxmodel-element-size");
|
||||
this._geometryEditorHighlighter = null;
|
||||
this._cssProperties = getCssProperties(inspector.toolbox);
|
||||
|
||||
this.init();
|
||||
}
|
||||
|
||||
BoxModelView.prototype = {
|
||||
init: function () {
|
||||
this.update = this.update.bind(this);
|
||||
|
||||
this.onNewSelection = this.onNewSelection.bind(this);
|
||||
this.inspector.selection.on("new-node-front", this.onNewSelection);
|
||||
|
||||
this.onNewNode = this.onNewNode.bind(this);
|
||||
this.inspector.sidebar.on("computedview-selected", this.onNewNode);
|
||||
|
||||
this.onSidebarSelect = this.onSidebarSelect.bind(this);
|
||||
this.inspector.sidebar.on("select", this.onSidebarSelect);
|
||||
|
||||
this.onToggleExpander = this.onToggleExpander.bind(this);
|
||||
this.expander.addEventListener("click", this.onToggleExpander);
|
||||
let header = this.doc.getElementById("old-boxmodel-header");
|
||||
header.addEventListener("dblclick", this.onToggleExpander);
|
||||
|
||||
this.onFilterComputedView = this.onFilterComputedView.bind(this);
|
||||
this.inspector.on("computed-view-filtered",
|
||||
this.onFilterComputedView);
|
||||
|
||||
this.onPickerStarted = this.onPickerStarted.bind(this);
|
||||
this.onMarkupViewLeave = this.onMarkupViewLeave.bind(this);
|
||||
this.onMarkupViewNodeHover = this.onMarkupViewNodeHover.bind(this);
|
||||
this.onWillNavigate = this.onWillNavigate.bind(this);
|
||||
this.onKeyDown = this.onKeyDown.bind(this);
|
||||
this.onLevelClick = this.onLevelClick.bind(this);
|
||||
this.setAriaActive = this.setAriaActive.bind(this);
|
||||
this.getEditBoxes = this.getEditBoxes.bind(this);
|
||||
this.makeFocusable = this.makeFocusable.bind(this);
|
||||
this.makeUnfocasable = this.makeUnfocasable.bind(this);
|
||||
this.moveFocus = this.moveFocus.bind(this);
|
||||
this.onFocus = this.onFocus.bind(this);
|
||||
|
||||
this.borderLayout = this.doc.getElementById("old-boxmodel-borders");
|
||||
this.boxModel = this.doc.getElementById("old-boxmodel-wrapper");
|
||||
this.marginLayout = this.doc.getElementById("old-boxmodel-margins");
|
||||
this.paddingLayout = this.doc.getElementById("old-boxmodel-padding");
|
||||
|
||||
this.layouts = {
|
||||
"margin": new Map([
|
||||
[KeyCodes.DOM_VK_ESCAPE, this.marginLayout],
|
||||
[KeyCodes.DOM_VK_DOWN, this.borderLayout],
|
||||
[KeyCodes.DOM_VK_UP, null],
|
||||
["click", this.marginLayout]
|
||||
]),
|
||||
"border": new Map([
|
||||
[KeyCodes.DOM_VK_ESCAPE, this.borderLayout],
|
||||
[KeyCodes.DOM_VK_DOWN, this.paddingLayout],
|
||||
[KeyCodes.DOM_VK_UP, this.marginLayout],
|
||||
["click", this.borderLayout]
|
||||
]),
|
||||
"padding": new Map([
|
||||
[KeyCodes.DOM_VK_ESCAPE, this.paddingLayout],
|
||||
[KeyCodes.DOM_VK_DOWN, null],
|
||||
[KeyCodes.DOM_VK_UP, this.borderLayout],
|
||||
["click", this.paddingLayout]
|
||||
])
|
||||
};
|
||||
|
||||
this.boxModel.addEventListener("click", this.onLevelClick, true);
|
||||
this.boxModel.addEventListener("focus", this.onFocus, true);
|
||||
this.boxModel.addEventListener("keydown", this.onKeyDown, true);
|
||||
|
||||
this.initBoxModelHighlighter();
|
||||
|
||||
// Store for the different dimensions of the node.
|
||||
// 'selector' refers to the element that holds the value;
|
||||
// 'property' is what we are measuring;
|
||||
// 'value' is the computed dimension, computed in update().
|
||||
this.map = {
|
||||
position: {
|
||||
selector: "#old-boxmodel-element-position",
|
||||
property: "position",
|
||||
value: undefined
|
||||
},
|
||||
marginTop: {
|
||||
selector: ".old-boxmodel-margin.old-boxmodel-top > span",
|
||||
property: "margin-top",
|
||||
value: undefined
|
||||
},
|
||||
marginBottom: {
|
||||
selector: ".old-boxmodel-margin.old-boxmodel-bottom > span",
|
||||
property: "margin-bottom",
|
||||
value: undefined
|
||||
},
|
||||
marginLeft: {
|
||||
selector: ".old-boxmodel-margin.old-boxmodel-left > span",
|
||||
property: "margin-left",
|
||||
value: undefined
|
||||
},
|
||||
marginRight: {
|
||||
selector: ".old-boxmodel-margin.old-boxmodel-right > span",
|
||||
property: "margin-right",
|
||||
value: undefined
|
||||
},
|
||||
paddingTop: {
|
||||
selector: ".old-boxmodel-padding.old-boxmodel-top > span",
|
||||
property: "padding-top",
|
||||
value: undefined
|
||||
},
|
||||
paddingBottom: {
|
||||
selector: ".old-boxmodel-padding.old-boxmodel-bottom > span",
|
||||
property: "padding-bottom",
|
||||
value: undefined
|
||||
},
|
||||
paddingLeft: {
|
||||
selector: ".old-boxmodel-padding.old-boxmodel-left > span",
|
||||
property: "padding-left",
|
||||
value: undefined
|
||||
},
|
||||
paddingRight: {
|
||||
selector: ".old-boxmodel-padding.old-boxmodel-right > span",
|
||||
property: "padding-right",
|
||||
value: undefined
|
||||
},
|
||||
borderTop: {
|
||||
selector: ".old-boxmodel-border.old-boxmodel-top > span",
|
||||
property: "border-top-width",
|
||||
value: undefined
|
||||
},
|
||||
borderBottom: {
|
||||
selector: ".old-boxmodel-border.old-boxmodel-bottom > span",
|
||||
property: "border-bottom-width",
|
||||
value: undefined
|
||||
},
|
||||
borderLeft: {
|
||||
selector: ".old-boxmodel-border.old-boxmodel-left > span",
|
||||
property: "border-left-width",
|
||||
value: undefined
|
||||
},
|
||||
borderRight: {
|
||||
selector: ".old-boxmodel-border.old-boxmodel-right > span",
|
||||
property: "border-right-width",
|
||||
value: undefined
|
||||
}
|
||||
};
|
||||
|
||||
// Make each element the dimensions editable
|
||||
for (let i in this.map) {
|
||||
if (i == "position") {
|
||||
continue;
|
||||
}
|
||||
|
||||
let dimension = this.map[i];
|
||||
editableItem({
|
||||
element: this.doc.querySelector(dimension.selector)
|
||||
}, (element, event) => {
|
||||
this.initEditor(element, event, dimension);
|
||||
});
|
||||
}
|
||||
|
||||
this.onNewNode();
|
||||
|
||||
let nodeGeometry = this.doc.getElementById("old-layout-geometry-editor");
|
||||
this.onGeometryButtonClick = this.onGeometryButtonClick.bind(this);
|
||||
nodeGeometry.addEventListener("click", this.onGeometryButtonClick);
|
||||
},
|
||||
|
||||
initBoxModelHighlighter: function () {
|
||||
let highlightElts = this.doc.querySelectorAll("#old-boxmodel-container *[title]");
|
||||
this.onHighlightMouseOver = this.onHighlightMouseOver.bind(this);
|
||||
this.onHighlightMouseOut = this.onHighlightMouseOut.bind(this);
|
||||
|
||||
for (let element of highlightElts) {
|
||||
element.addEventListener("mouseover", this.onHighlightMouseOver, true);
|
||||
element.addEventListener("mouseout", this.onHighlightMouseOut, true);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Start listening to reflows in the current tab.
|
||||
*/
|
||||
trackReflows: function () {
|
||||
if (!this.reflowFront) {
|
||||
let { target } = this.inspector;
|
||||
if (target.form.reflowActor) {
|
||||
this.reflowFront = ReflowFront(target.client,
|
||||
target.form);
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
this.reflowFront.on("reflows", this.update);
|
||||
this.reflowFront.start();
|
||||
},
|
||||
|
||||
/**
|
||||
* Stop listening to reflows in the current tab.
|
||||
*/
|
||||
untrackReflows: function () {
|
||||
if (!this.reflowFront) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.reflowFront.off("reflows", this.update);
|
||||
this.reflowFront.stop();
|
||||
},
|
||||
|
||||
/**
|
||||
* Called when the user clicks on one of the editable values in the box model view
|
||||
*/
|
||||
initEditor: function (element, event, dimension) {
|
||||
let { property } = dimension;
|
||||
let session = new EditingSession(this);
|
||||
let initialValue = session.getProperty(property);
|
||||
|
||||
let editor = new InplaceEditor({
|
||||
element: element,
|
||||
initial: initialValue,
|
||||
contentType: InplaceEditor.CONTENT_TYPES.CSS_VALUE,
|
||||
property: {
|
||||
name: dimension.property
|
||||
},
|
||||
start: self => {
|
||||
self.elt.parentNode.classList.add("old-boxmodel-editing");
|
||||
},
|
||||
change: value => {
|
||||
if (NUMERIC.test(value)) {
|
||||
value += "px";
|
||||
}
|
||||
|
||||
let properties = [
|
||||
{ name: property, value: value }
|
||||
];
|
||||
|
||||
if (property.substring(0, 7) == "border-") {
|
||||
let bprop = property.substring(0, property.length - 5) + "style";
|
||||
let style = session.getProperty(bprop);
|
||||
if (!style || style == "none" || style == "hidden") {
|
||||
properties.push({ name: bprop, value: "solid" });
|
||||
}
|
||||
}
|
||||
|
||||
session.setProperties(properties).catch(e => console.error(e));
|
||||
},
|
||||
done: (value, commit) => {
|
||||
editor.elt.parentNode.classList.remove("old-boxmodel-editing");
|
||||
if (!commit) {
|
||||
session.revert().then(() => {
|
||||
session.destroy();
|
||||
}, e => console.error(e));
|
||||
}
|
||||
},
|
||||
contextMenu: this.inspector.onTextBoxContextMenu,
|
||||
cssProperties: this._cssProperties
|
||||
}, event);
|
||||
},
|
||||
|
||||
/**
|
||||
* Is the BoxModelView visible in the sidebar.
|
||||
* @return {Boolean}
|
||||
*/
|
||||
isViewVisible: function () {
|
||||
return this.inspector &&
|
||||
this.inspector.sidebar.getCurrentTabID() == "computedview";
|
||||
},
|
||||
|
||||
/**
|
||||
* Is the BoxModelView visible in the sidebar and is the current node valid to
|
||||
* be displayed in the view.
|
||||
* @return {Boolean}
|
||||
*/
|
||||
isViewVisibleAndNodeValid: function () {
|
||||
return this.isViewVisible() &&
|
||||
this.inspector.selection.isConnected() &&
|
||||
this.inspector.selection.isElementNode();
|
||||
},
|
||||
|
||||
/**
|
||||
* Destroy the nodes. Remove listeners.
|
||||
*/
|
||||
destroy: function () {
|
||||
let highlightElts = this.doc.querySelectorAll("#old-boxmodel-container *[title]");
|
||||
|
||||
for (let element of highlightElts) {
|
||||
element.removeEventListener("mouseover", this.onHighlightMouseOver, true);
|
||||
element.removeEventListener("mouseout", this.onHighlightMouseOut, true);
|
||||
}
|
||||
|
||||
this.expander.removeEventListener("click", this.onToggleExpander);
|
||||
let header = this.doc.getElementById("old-boxmodel-header");
|
||||
header.removeEventListener("dblclick", this.onToggleExpander);
|
||||
|
||||
let nodeGeometry = this.doc.getElementById("old-layout-geometry-editor");
|
||||
nodeGeometry.removeEventListener("click", this.onGeometryButtonClick);
|
||||
|
||||
this.boxModel.removeEventListener("click", this.onLevelClick, true);
|
||||
this.boxModel.removeEventListener("focus", this.onFocus, true);
|
||||
this.boxModel.removeEventListener("keydown", this.onKeyDown, true);
|
||||
|
||||
this.inspector.off("picker-started", this.onPickerStarted);
|
||||
|
||||
// Inspector Panel will destroy `markup` object on "will-navigate" event,
|
||||
// therefore we have to check if it's still available in case BoxModelView
|
||||
// is destroyed immediately after.
|
||||
if (this.inspector.markup) {
|
||||
this.inspector.markup.off("leave", this.onMarkupViewLeave);
|
||||
this.inspector.markup.off("node-hover", this.onMarkupViewNodeHover);
|
||||
}
|
||||
|
||||
this.inspector.sidebar.off("computedview-selected", this.onNewNode);
|
||||
this.inspector.selection.off("new-node-front", this.onNewSelection);
|
||||
this.inspector.sidebar.off("select", this.onSidebarSelect);
|
||||
this.inspector.target.off("will-navigate", this.onWillNavigate);
|
||||
this.inspector.off("computed-view-filtered", this.onFilterComputedView);
|
||||
|
||||
this.inspector = null;
|
||||
this.doc = null;
|
||||
this.wrapper = null;
|
||||
this.container = null;
|
||||
this.expander = null;
|
||||
this.sizeLabel = null;
|
||||
this.sizeHeadingLabel = null;
|
||||
|
||||
this.marginLayout = null;
|
||||
this.borderLayout = null;
|
||||
this.paddingLayout = null;
|
||||
this.boxModel = null;
|
||||
this.layouts = null;
|
||||
|
||||
if (this.reflowFront) {
|
||||
this.untrackReflows();
|
||||
this.reflowFront.destroy();
|
||||
this.reflowFront = null;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Set initial box model focus to the margin layout.
|
||||
*/
|
||||
onFocus: function () {
|
||||
let activeDescendant = this.boxModel.getAttribute("aria-activedescendant");
|
||||
|
||||
if (!activeDescendant) {
|
||||
let nextLayout = this.marginLayout;
|
||||
this.setAriaActive(nextLayout);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Active aria-level set to current layout.
|
||||
*
|
||||
* @param {Element} nextLayout
|
||||
* Element of next layout that user has navigated to
|
||||
* @param {Node} target
|
||||
* Node to be observed
|
||||
*/
|
||||
setAriaActive: function (nextLayout, target) {
|
||||
this.boxModel.setAttribute("aria-activedescendant", nextLayout.id);
|
||||
if (target && target._editable) {
|
||||
target.blur();
|
||||
}
|
||||
|
||||
// Clear all
|
||||
this.marginLayout.classList.remove("layout-active-elm");
|
||||
this.borderLayout.classList.remove("layout-active-elm");
|
||||
this.paddingLayout.classList.remove("layout-active-elm");
|
||||
|
||||
// Set the next level's border outline
|
||||
nextLayout.classList.add("layout-active-elm");
|
||||
},
|
||||
|
||||
/**
|
||||
* Update aria-active on mouse click.
|
||||
*
|
||||
* @param {Event} event
|
||||
* The event triggered by a mouse click on the box model
|
||||
*/
|
||||
onLevelClick: function (event) {
|
||||
let {target} = event;
|
||||
let nextLayout = this.layouts[target.getAttribute("data-box")].get("click");
|
||||
|
||||
this.setAriaActive(nextLayout, target);
|
||||
},
|
||||
|
||||
/**
|
||||
* Handle keyboard navigation and focus for box model layouts.
|
||||
*
|
||||
* Updates active layout on arrow key navigation
|
||||
* Focuses next layout's editboxes on enter key
|
||||
* Unfocuses current layout's editboxes when active layout changes
|
||||
* Controls tabbing between editBoxes
|
||||
*
|
||||
* @param {Event} event
|
||||
* The event triggered by a keypress on the box model
|
||||
*/
|
||||
onKeyDown: function (event) {
|
||||
let {target, keyCode} = event;
|
||||
// If focused on editable value or in editing mode
|
||||
let isEditable = target._editable || target.editor;
|
||||
let level = this.boxModel.getAttribute("aria-activedescendant");
|
||||
let editingMode = target.tagName === "input";
|
||||
let nextLayout;
|
||||
|
||||
switch (keyCode) {
|
||||
case KeyCodes.DOM_VK_RETURN:
|
||||
if (!isEditable) {
|
||||
this.makeFocusable(level);
|
||||
}
|
||||
break;
|
||||
case KeyCodes.DOM_VK_DOWN:
|
||||
case KeyCodes.DOM_VK_UP:
|
||||
if (!editingMode) {
|
||||
event.preventDefault();
|
||||
this.makeUnfocasable(level);
|
||||
let datalevel = this.doc.getElementById(level).getAttribute("data-box");
|
||||
nextLayout = this.layouts[datalevel].get(keyCode);
|
||||
this.boxModel.focus();
|
||||
}
|
||||
break;
|
||||
case KeyCodes.DOM_VK_TAB:
|
||||
if (isEditable) {
|
||||
event.preventDefault();
|
||||
this.moveFocus(event, level);
|
||||
}
|
||||
break;
|
||||
case KeyCodes.DOM_VK_ESCAPE:
|
||||
if (isEditable && target._editable) {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
this.makeUnfocasable(level);
|
||||
this.boxModel.focus();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (nextLayout) {
|
||||
this.setAriaActive(nextLayout, target);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Make previous layout's elements unfocusable.
|
||||
*
|
||||
* @param {String} editLevel
|
||||
* The previous layout
|
||||
*/
|
||||
makeUnfocasable: function (editLevel) {
|
||||
let editBoxes = this.getEditBoxes(editLevel);
|
||||
editBoxes.forEach(editBox => editBox.setAttribute("tabindex", "-1"));
|
||||
},
|
||||
|
||||
/**
|
||||
* Make current layout's elements focusable.
|
||||
*
|
||||
* @param {String} editLevel
|
||||
* The current layout
|
||||
*/
|
||||
makeFocusable: function (editLevel) {
|
||||
let editBoxes = this.getEditBoxes(editLevel);
|
||||
editBoxes.forEach(editBox => editBox.setAttribute("tabindex", "0"));
|
||||
editBoxes[0].focus();
|
||||
},
|
||||
|
||||
/**
|
||||
* Keyboard navigation of edit boxes wraps around on edge
|
||||
* elements ([layout]-top, [layout]-left).
|
||||
*
|
||||
* @param {Node} target
|
||||
* Node to be observed
|
||||
* @param {Boolean} shiftKey
|
||||
* Determines if shiftKey was pressed
|
||||
* @param {String} level
|
||||
* Current active layout
|
||||
*/
|
||||
moveFocus: function ({target, shiftKey}, level) {
|
||||
let editBoxes = this.getEditBoxes(level);
|
||||
let editingMode = target.tagName === "input";
|
||||
// target.nextSibling is input field
|
||||
let position = editingMode ? editBoxes.indexOf(target.nextSibling)
|
||||
: editBoxes.indexOf(target);
|
||||
|
||||
if (position === editBoxes.length - 1 && !shiftKey) {
|
||||
position = 0;
|
||||
} else if (position === 0 && shiftKey) {
|
||||
position = editBoxes.length - 1;
|
||||
} else {
|
||||
shiftKey ? position-- : position++;
|
||||
}
|
||||
|
||||
let editBox = editBoxes[position];
|
||||
editBox.focus();
|
||||
|
||||
if (editingMode) {
|
||||
editBox.click();
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Retrieve edit boxes for current layout.
|
||||
*
|
||||
* @param {String} editLevel
|
||||
* Current active layout
|
||||
* @return Layout's edit boxes
|
||||
*/
|
||||
getEditBoxes: function (editLevel) {
|
||||
let dataLevel = this.doc.getElementById(editLevel).getAttribute("data-box");
|
||||
return [...this.doc.querySelectorAll(
|
||||
`[data-box="${dataLevel}"].old-boxmodel-editable`)];
|
||||
},
|
||||
|
||||
onSidebarSelect: function (e, sidebar) {
|
||||
this.setActive(sidebar === "computedview");
|
||||
},
|
||||
|
||||
/**
|
||||
* Selection 'new-node-front' event handler.
|
||||
*/
|
||||
onNewSelection: function () {
|
||||
let done = this.inspector.updating("computed-view");
|
||||
this.onNewNode()
|
||||
.then(() => this.hideGeometryEditor())
|
||||
.then(done, (err) => {
|
||||
console.error(err);
|
||||
done();
|
||||
}).catch(console.error);
|
||||
},
|
||||
|
||||
/**
|
||||
* @return a promise that resolves when the view has been updated
|
||||
*/
|
||||
onNewNode: function () {
|
||||
this.setActive(this.isViewVisibleAndNodeValid());
|
||||
return this.update();
|
||||
},
|
||||
|
||||
onHighlightMouseOver: function (e) {
|
||||
let region = e.target.getAttribute("data-box");
|
||||
if (!region) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.showBoxModel({
|
||||
region,
|
||||
showOnly: region,
|
||||
onlyRegionArea: true
|
||||
});
|
||||
},
|
||||
|
||||
onHighlightMouseOut: function () {
|
||||
this.hideBoxModel();
|
||||
},
|
||||
|
||||
onGeometryButtonClick: function ({target}) {
|
||||
if (target.hasAttribute("checked")) {
|
||||
target.removeAttribute("checked");
|
||||
this.hideGeometryEditor();
|
||||
} else {
|
||||
target.setAttribute("checked", "true");
|
||||
this.showGeometryEditor();
|
||||
}
|
||||
},
|
||||
|
||||
onPickerStarted: function () {
|
||||
this.hideGeometryEditor();
|
||||
},
|
||||
|
||||
onToggleExpander: function () {
|
||||
let isOpen = this.expander.hasAttribute("open");
|
||||
|
||||
if (isOpen) {
|
||||
this.container.hidden = true;
|
||||
this.expander.removeAttribute("open");
|
||||
} else {
|
||||
this.container.hidden = false;
|
||||
this.expander.setAttribute("open", "");
|
||||
}
|
||||
},
|
||||
|
||||
onMarkupViewLeave: function () {
|
||||
this.showGeometryEditor(true);
|
||||
},
|
||||
|
||||
onMarkupViewNodeHover: function () {
|
||||
this.hideGeometryEditor(false);
|
||||
},
|
||||
|
||||
onWillNavigate: function () {
|
||||
this._geometryEditorHighlighter.release().catch(console.error);
|
||||
this._geometryEditorHighlighter = null;
|
||||
},
|
||||
|
||||
/**
|
||||
* Event handler that responds to the computed view being filtered
|
||||
* @param {String} reason
|
||||
* @param {Boolean} hidden
|
||||
* Whether or not to hide the box model wrapper
|
||||
*/
|
||||
onFilterComputedView: function (reason, hidden) {
|
||||
this.wrapper.hidden = hidden;
|
||||
},
|
||||
|
||||
/**
|
||||
* Stop tracking reflows and hide all values when no node is selected or the
|
||||
* box model view is hidden, otherwise track reflows and show values.
|
||||
* @param {Boolean} isActive
|
||||
*/
|
||||
setActive: function (isActive) {
|
||||
if (isActive === this.isActive) {
|
||||
return;
|
||||
}
|
||||
this.isActive = isActive;
|
||||
|
||||
if (isActive) {
|
||||
this.trackReflows();
|
||||
} else {
|
||||
this.untrackReflows();
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Compute the dimensions of the node and update the values in
|
||||
* the inspector.xul document.
|
||||
* @return a promise that will be resolved when complete.
|
||||
*/
|
||||
update: function () {
|
||||
let lastRequest = Task.spawn((function* () {
|
||||
if (!this.isViewVisibleAndNodeValid()) {
|
||||
this.wrapper.hidden = true;
|
||||
this.inspector.emit("boxmodel-view-updated");
|
||||
return null;
|
||||
}
|
||||
|
||||
let node = this.inspector.selection.nodeFront;
|
||||
let layout = yield this.inspector.pageStyle.getLayout(node, {
|
||||
autoMargins: this.isActive
|
||||
});
|
||||
let styleEntries = yield this.inspector.pageStyle.getApplied(node, {});
|
||||
|
||||
yield this.updateGeometryButton();
|
||||
|
||||
// If a subsequent request has been made, wait for that one instead.
|
||||
if (this._lastRequest != lastRequest) {
|
||||
return this._lastRequest;
|
||||
}
|
||||
|
||||
this._lastRequest = null;
|
||||
let width = layout.width;
|
||||
let height = layout.height;
|
||||
let newLabel = SHARED_L10N.getFormatStr("dimensions", width, height);
|
||||
|
||||
if (this.sizeHeadingLabel.textContent != newLabel) {
|
||||
this.sizeHeadingLabel.textContent = newLabel;
|
||||
}
|
||||
|
||||
for (let i in this.map) {
|
||||
let property = this.map[i].property;
|
||||
if (!(property in layout)) {
|
||||
// Depending on the actor version, some properties
|
||||
// might be missing.
|
||||
continue;
|
||||
}
|
||||
let parsedValue = parseFloat(layout[property]);
|
||||
if (Number.isNaN(parsedValue)) {
|
||||
// Not a number. We use the raw string.
|
||||
// Useful for "position" for example.
|
||||
this.map[i].value = layout[property];
|
||||
} else {
|
||||
this.map[i].value = parsedValue;
|
||||
}
|
||||
}
|
||||
|
||||
let margins = layout.autoMargins;
|
||||
if ("top" in margins) {
|
||||
this.map.marginTop.value = "auto";
|
||||
}
|
||||
if ("right" in margins) {
|
||||
this.map.marginRight.value = "auto";
|
||||
}
|
||||
if ("bottom" in margins) {
|
||||
this.map.marginBottom.value = "auto";
|
||||
}
|
||||
if ("left" in margins) {
|
||||
this.map.marginLeft.value = "auto";
|
||||
}
|
||||
|
||||
for (let i in this.map) {
|
||||
let selector = this.map[i].selector;
|
||||
let span = this.doc.querySelector(selector);
|
||||
this.updateSourceRuleTooltip(span, this.map[i].property, styleEntries);
|
||||
if (span.textContent.length > 0 &&
|
||||
span.textContent == this.map[i].value) {
|
||||
continue;
|
||||
}
|
||||
span.textContent = this.map[i].value;
|
||||
this.manageOverflowingText(span);
|
||||
}
|
||||
|
||||
width -= this.map.borderLeft.value + this.map.borderRight.value +
|
||||
this.map.paddingLeft.value + this.map.paddingRight.value;
|
||||
width = parseFloat(width.toPrecision(6));
|
||||
height -= this.map.borderTop.value + this.map.borderBottom.value +
|
||||
this.map.paddingTop.value + this.map.paddingBottom.value;
|
||||
height = parseFloat(height.toPrecision(6));
|
||||
|
||||
let newValue = width + "\u00D7" + height;
|
||||
if (this.sizeLabel.textContent != newValue) {
|
||||
this.sizeLabel.textContent = newValue;
|
||||
}
|
||||
|
||||
this.elementRules = styleEntries.map(e => e.rule);
|
||||
|
||||
this.wrapper.hidden = false;
|
||||
|
||||
this.inspector.emit("boxmodel-view-updated");
|
||||
return null;
|
||||
}).bind(this)).catch(console.error);
|
||||
|
||||
this._lastRequest = lastRequest;
|
||||
return this._lastRequest;
|
||||
},
|
||||
|
||||
/**
|
||||
* Update the text in the tooltip shown when hovering over a value to provide
|
||||
* information about the source CSS rule that sets this value.
|
||||
* @param {DOMNode} el The element that will receive the tooltip.
|
||||
* @param {String} property The name of the CSS property for the tooltip.
|
||||
* @param {Array} rules An array of applied rules retrieved by
|
||||
* styleActor.getApplied.
|
||||
*/
|
||||
updateSourceRuleTooltip: function (el, property, rules) {
|
||||
// Dummy element used to parse the cssText of applied rules.
|
||||
let dummyEl = this.doc.createElement("div");
|
||||
|
||||
// Rules are in order of priority so iterate until we find the first that
|
||||
// defines a value for the property.
|
||||
let sourceRule, value;
|
||||
for (let {rule} of rules) {
|
||||
dummyEl.style.cssText = rule.cssText;
|
||||
value = dummyEl.style.getPropertyValue(property);
|
||||
if (value !== "") {
|
||||
sourceRule = rule;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
let title = property;
|
||||
if (sourceRule && sourceRule.selectors) {
|
||||
title += "\n" + sourceRule.selectors.join(", ");
|
||||
}
|
||||
if (sourceRule && sourceRule.parentStyleSheet) {
|
||||
if (sourceRule.parentStyleSheet.href) {
|
||||
title += "\n" + sourceRule.parentStyleSheet.href + ":" + sourceRule.line;
|
||||
} else {
|
||||
title += "\n" + INSPECTOR_L10N.getStr("rule.sourceInline") +
|
||||
":" + sourceRule.line;
|
||||
}
|
||||
}
|
||||
|
||||
el.setAttribute("title", title);
|
||||
},
|
||||
|
||||
/**
|
||||
* Show the box-model highlighter on the currently selected element
|
||||
* @param {Object} options Options passed to the highlighter actor
|
||||
*/
|
||||
showBoxModel: function (options = {}) {
|
||||
let toolbox = this.inspector.toolbox;
|
||||
let nodeFront = this.inspector.selection.nodeFront;
|
||||
|
||||
toolbox.highlighterUtils.highlightNodeFront(nodeFront, options);
|
||||
},
|
||||
|
||||
/**
|
||||
* Hide the box-model highlighter on the currently selected element
|
||||
*/
|
||||
hideBoxModel: function () {
|
||||
let toolbox = this.inspector.toolbox;
|
||||
|
||||
toolbox.highlighterUtils.unhighlight();
|
||||
},
|
||||
|
||||
/**
|
||||
* Show the geometry editor highlighter on the currently selected element
|
||||
* @param {Boolean} [showOnlyIfActive=false]
|
||||
* Indicates if the Geometry Editor should be shown only if it's active but
|
||||
* hidden.
|
||||
*/
|
||||
showGeometryEditor: function (showOnlyIfActive = false) {
|
||||
let toolbox = this.inspector.toolbox;
|
||||
let nodeFront = this.inspector.selection.nodeFront;
|
||||
let nodeGeometry = this.doc.getElementById("old-layout-geometry-editor");
|
||||
let isActive = nodeGeometry.hasAttribute("checked");
|
||||
|
||||
if (showOnlyIfActive && !isActive) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (this._geometryEditorHighlighter) {
|
||||
this._geometryEditorHighlighter.show(nodeFront).catch(console.error);
|
||||
return;
|
||||
}
|
||||
|
||||
// instantiate Geometry Editor highlighter
|
||||
toolbox.highlighterUtils
|
||||
.getHighlighterByType("GeometryEditorHighlighter").then(highlighter => {
|
||||
highlighter.show(nodeFront).catch(console.error);
|
||||
this._geometryEditorHighlighter = highlighter;
|
||||
|
||||
// Hide completely the geometry editor if the picker is clicked
|
||||
toolbox.on("picker-started", this.onPickerStarted);
|
||||
|
||||
// Temporary hide the geometry editor
|
||||
this.inspector.markup.on("leave", this.onMarkupViewLeave);
|
||||
this.inspector.markup.on("node-hover", this.onMarkupViewNodeHover);
|
||||
|
||||
// Release the actor on will-navigate event
|
||||
this.inspector.target.once("will-navigate", this.onWillNavigate);
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Hide the geometry editor highlighter on the currently selected element
|
||||
* @param {Boolean} [updateButton=true]
|
||||
* Indicates if the Geometry Editor's button needs to be unchecked too
|
||||
*/
|
||||
hideGeometryEditor: function (updateButton = true) {
|
||||
if (this._geometryEditorHighlighter) {
|
||||
this._geometryEditorHighlighter.hide().catch(console.error);
|
||||
}
|
||||
|
||||
if (updateButton) {
|
||||
let nodeGeometry = this.doc.getElementById("old-layout-geometry-editor");
|
||||
nodeGeometry.removeAttribute("checked");
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Update the visibility and the state of the geometry editor button,
|
||||
* based on the selected node.
|
||||
*/
|
||||
updateGeometryButton: Task.async(function* () {
|
||||
let node = this.inspector.selection.nodeFront;
|
||||
let isEditable = false;
|
||||
|
||||
if (node) {
|
||||
isEditable = yield this.inspector.pageStyle.isPositionEditable(node);
|
||||
}
|
||||
|
||||
let nodeGeometry = this.doc.getElementById("old-layout-geometry-editor");
|
||||
nodeGeometry.style.visibility = isEditable ? "visible" : "hidden";
|
||||
}),
|
||||
|
||||
manageOverflowingText: function (span) {
|
||||
let classList = span.parentNode.classList;
|
||||
|
||||
if (classList.contains("old-boxmodel-left") ||
|
||||
classList.contains("old-boxmodel-right")) {
|
||||
let force = span.textContent.length > LONG_TEXT_ROTATE_LIMIT;
|
||||
classList.toggle("old-boxmodel-rotate", force);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = BoxModelView;
|
|
@ -5,9 +5,6 @@
|
|||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
DevToolsModules(
|
||||
'deprecated-box-model.js',
|
||||
'inspector-tab-panel.css',
|
||||
'inspector-tab-panel.js',
|
||||
)
|
||||
|
||||
BROWSER_CHROME_MANIFESTS += ['test/browser.ini']
|
||||
|
|
|
@ -1,49 +0,0 @@
|
|||
/* vim: set ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
// Test that longer values are rotated on the side
|
||||
|
||||
const res1 = [
|
||||
{selector: ".old-boxmodel-margin.old-boxmodel-top > span", value: 30},
|
||||
{selector: ".old-boxmodel-margin.old-boxmodel-left > span", value: "auto"},
|
||||
{selector: ".old-boxmodel-margin.old-boxmodel-bottom > span", value: 30},
|
||||
{selector: ".old-boxmodel-margin.old-boxmodel-right > span", value: "auto"},
|
||||
{selector: ".old-boxmodel-padding.old-boxmodel-top > span", value: 20},
|
||||
{selector: ".old-boxmodel-padding.old-boxmodel-left > span", value: 2000000},
|
||||
{selector: ".old-boxmodel-padding.old-boxmodel-bottom > span", value: 20},
|
||||
{selector: ".old-boxmodel-padding.old-boxmodel-right > span", value: 20},
|
||||
{selector: ".old-boxmodel-border.old-boxmodel-top > span", value: 10},
|
||||
{selector: ".old-boxmodel-border.old-boxmodel-left > span", value: 10},
|
||||
{selector: ".old-boxmodel-border.old-boxmodel-bottom > span", value: 10},
|
||||
{selector: ".old-boxmodel-border.old-boxmodel-right > span", value: 10},
|
||||
];
|
||||
|
||||
const TEST_URI = encodeURIComponent([
|
||||
"<style>",
|
||||
"div { border:10px solid black; padding: 20px 20px 20px 2000000px; " +
|
||||
"margin: 30px auto; }",
|
||||
"</style>",
|
||||
"<div></div>"
|
||||
].join(""));
|
||||
const LONG_TEXT_ROTATE_LIMIT = 3;
|
||||
|
||||
add_task(function* () {
|
||||
yield addTab("data:text/html," + TEST_URI);
|
||||
let {inspector, view} = yield openBoxModelView();
|
||||
yield selectNode("div", inspector);
|
||||
|
||||
for (let i = 0; i < res1.length; i++) {
|
||||
let elt = view.doc.querySelector(res1[i].selector);
|
||||
let isLong = elt.textContent.length > LONG_TEXT_ROTATE_LIMIT;
|
||||
let classList = elt.parentNode.classList;
|
||||
let canBeRotated = classList.contains("old-boxmodel-left") ||
|
||||
classList.contains("old-boxmodel-right");
|
||||
let isRotated = classList.contains("old-boxmodel-rotate");
|
||||
|
||||
is(canBeRotated && isLong,
|
||||
isRotated, res1[i].selector + " correctly rotated.");
|
||||
}
|
||||
});
|
|
@ -26,9 +26,14 @@ const {
|
|||
const StyleInspectorMenu = require("devtools/client/inspector/shared/style-inspector-menu");
|
||||
const TooltipsOverlay = require("devtools/client/inspector/shared/tooltips-overlay");
|
||||
const KeyShortcuts = require("devtools/client/shared/key-shortcuts");
|
||||
const BoxModelView = require("devtools/client/inspector/components/deprecated-box-model");
|
||||
const clipboardHelper = require("devtools/shared/platform/clipboard");
|
||||
|
||||
const { createElement, createFactory } = require("devtools/client/shared/vendor/react");
|
||||
const ReactDOM = require("devtools/client/shared/vendor/react-dom");
|
||||
const { Provider } = require("devtools/client/shared/vendor/react-redux");
|
||||
|
||||
const BoxModelApp = createFactory(require("devtools/client/inspector/boxmodel/components/BoxModelApp"));
|
||||
|
||||
const STYLE_INSPECTOR_PROPERTIES = "devtools/shared/locales/styleinspector.properties";
|
||||
const {LocalizationHelper} = require("devtools/shared/l10n");
|
||||
const STYLE_INSPECTOR_L10N = new LocalizationHelper(STYLE_INSPECTOR_PROPERTIES);
|
||||
|
@ -154,6 +159,7 @@ UpdateProcess.prototype = {
|
|||
function CssComputedView(inspector, document, pageStyle) {
|
||||
this.inspector = inspector;
|
||||
this.highlighters = inspector.highlighters;
|
||||
this.store = inspector.store;
|
||||
this.styleDocument = document;
|
||||
this.styleWindow = this.styleDocument.defaultView;
|
||||
this.pageStyle = pageStyle;
|
||||
|
@ -174,6 +180,7 @@ function CssComputedView(inspector, document, pageStyle) {
|
|||
|
||||
let doc = this.styleDocument;
|
||||
this.element = doc.getElementById("propertyContainer");
|
||||
this.boxModelWrapper = doc.getElementById("boxmodel-wrapper");
|
||||
this.searchField = doc.getElementById("computedview-searchbox");
|
||||
this.searchClearButton = doc.getElementById("computedview-searchinput-clear");
|
||||
this.includeBrowserStylesCheckbox =
|
||||
|
@ -209,6 +216,7 @@ function CssComputedView(inspector, document, pageStyle) {
|
|||
// The element that we're inspecting, and the document that it comes from.
|
||||
this._viewedElement = null;
|
||||
|
||||
this.createBoxModelView();
|
||||
this.createStyleViews();
|
||||
|
||||
this._contextmenu = new StyleInspectorMenu(this, { isRuleView: false });
|
||||
|
@ -552,10 +560,10 @@ CssComputedView.prototype = {
|
|||
this._filterChangedTimeout = setTimeout(() => {
|
||||
if (this.searchField.value.length > 0) {
|
||||
this.searchField.setAttribute("filled", true);
|
||||
this.inspector.emit("computed-view-filtered", true);
|
||||
this.boxModelWrapper.hidden = true;
|
||||
} else {
|
||||
this.searchField.removeAttribute("filled");
|
||||
this.inspector.emit("computed-view-filtered", false);
|
||||
this.boxModelWrapper.hidden = false;
|
||||
}
|
||||
|
||||
this.refreshPanel();
|
||||
|
@ -605,6 +613,29 @@ CssComputedView.prototype = {
|
|||
this.inspector.emit("computed-view-sourcelinks-updated");
|
||||
},
|
||||
|
||||
/**
|
||||
* Render the box model view.
|
||||
*/
|
||||
createBoxModelView: function () {
|
||||
let {
|
||||
onHideBoxModelHighlighter,
|
||||
onShowBoxModelEditor,
|
||||
onShowBoxModelHighlighter,
|
||||
} = this.inspector.boxmodel.getComponentProps();
|
||||
|
||||
let provider = createElement(
|
||||
Provider,
|
||||
{ store: this.store },
|
||||
BoxModelApp({
|
||||
showBoxModelProperties: false,
|
||||
onHideBoxModelHighlighter,
|
||||
onShowBoxModelEditor,
|
||||
onShowBoxModelHighlighter,
|
||||
})
|
||||
);
|
||||
ReactDOM.render(provider, this.boxModelWrapper);
|
||||
},
|
||||
|
||||
/**
|
||||
* The CSS as displayed by the UI.
|
||||
*/
|
||||
|
@ -783,7 +814,7 @@ CssComputedView.prototype = {
|
|||
|
||||
// Nodes used in templating
|
||||
this.element = null;
|
||||
this.panel = null;
|
||||
this.boxModelWrapper = null;
|
||||
this.searchField = null;
|
||||
this.searchClearButton = null;
|
||||
this.includeBrowserStylesCheckbox = null;
|
||||
|
@ -796,6 +827,7 @@ CssComputedView.prototype = {
|
|||
|
||||
this.inspector = null;
|
||||
this.highlighters = null;
|
||||
this.store = null;
|
||||
this.styleDocument = null;
|
||||
this.styleWindow = null;
|
||||
|
||||
|
@ -1416,7 +1448,6 @@ function ComputedViewTool(inspector, window) {
|
|||
|
||||
this.computedView = new CssComputedView(this.inspector, this.document,
|
||||
this.inspector.pageStyle);
|
||||
this.boxModelView = new BoxModelView(this.inspector, this.document);
|
||||
|
||||
this.onSelected = this.onSelected.bind(this);
|
||||
this.refresh = this.refresh.bind(this);
|
||||
|
@ -1525,9 +1556,8 @@ ComputedViewTool.prototype = {
|
|||
}
|
||||
|
||||
this.computedView.destroy();
|
||||
this.boxModelView.destroy();
|
||||
|
||||
this.computedView = this.boxModelView = this.document = this.inspector = null;
|
||||
this.computedView = this.document = this.inspector = null;
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -34,7 +34,7 @@ function* testToggleDefaultStyles(inspector, computedView) {
|
|||
function* testAddTextInFilter(inspector, computedView) {
|
||||
info("setting filter text to \"color\"");
|
||||
let doc = computedView.styleDocument;
|
||||
let boxModelWrapper = doc.querySelector("#old-boxmodel-wrapper");
|
||||
let boxModelWrapper = doc.getElementById("boxmodel-wrapper");
|
||||
let searchField = computedView.searchField;
|
||||
let onRefreshed = inspector.once("computed-view-refreshed");
|
||||
let win = computedView.styleWindow;
|
||||
|
|
|
@ -50,7 +50,7 @@ function* testClearSearchFilter(inspector, computedView) {
|
|||
|
||||
let win = computedView.styleWindow;
|
||||
let doc = computedView.styleDocument;
|
||||
let boxModelWrapper = doc.querySelector("#old-boxmodel-wrapper");
|
||||
let boxModelWrapper = doc.getElementById("boxmodel-wrapper");
|
||||
let propertyViews = computedView.propertyViews;
|
||||
let searchField = computedView.searchField;
|
||||
let searchClearButton = computedView.searchClearButton;
|
||||
|
|
|
@ -23,7 +23,7 @@ const Menu = require("devtools/client/framework/menu");
|
|||
const MenuItem = require("devtools/client/framework/menu-item");
|
||||
|
||||
const {HTMLBreadcrumbs} = require("devtools/client/inspector/breadcrumbs");
|
||||
const {ComputedViewTool} = require("devtools/client/inspector/computed/computed");
|
||||
const BoxModel = require("devtools/client/inspector/boxmodel/box-model");
|
||||
const {FontInspector} = require("devtools/client/inspector/fonts/fonts");
|
||||
const {InspectorSearch} = require("devtools/client/inspector/inspector-search");
|
||||
const {RuleViewTool} = require("devtools/client/inspector/rules/rules");
|
||||
|
@ -78,8 +78,6 @@ const PORTRAIT_MODE_WIDTH = 700;
|
|||
* - computed-view-sourcelinks-updated
|
||||
* Fired when the stylesheet source links have been updated (when switching
|
||||
* to source-mapped files)
|
||||
* - computed-view-filtered
|
||||
* Fired when the computed rules view is filtered
|
||||
* - rule-view-refreshed
|
||||
* Fired when the rule view updates to a new node
|
||||
* - rule-view-sourcelinks-updated
|
||||
|
@ -572,6 +570,10 @@ Inspector.prototype = {
|
|||
defaultTab == "computedview");
|
||||
|
||||
this.ruleview = new RuleViewTool(this, this.panelWin);
|
||||
this.boxmodel = new BoxModel(this, this.panelWin);
|
||||
|
||||
const {ComputedViewTool} =
|
||||
this.browserRequire("devtools/client/inspector/computed/computed");
|
||||
this.computedview = new ComputedViewTool(this, this.panelWin);
|
||||
|
||||
if (Services.prefs.getBoolPref("devtools.layoutview.enabled")) {
|
||||
|
|
|
@ -14,7 +14,6 @@
|
|||
<link rel="stylesheet" href="chrome://devtools/skin/computed.css"/>
|
||||
<link rel="stylesheet" href="chrome://devtools/skin/fonts.css"/>
|
||||
<link rel="stylesheet" href="chrome://devtools/skin/boxmodel.css"/>
|
||||
<link rel="stylesheet" href="chrome://devtools/skin/deprecated-boxmodel.css"/>
|
||||
<link rel="stylesheet" href="chrome://devtools/skin/layout.css"/>
|
||||
<link rel="stylesheet" href="chrome://devtools/skin/animationinspector.css"/>
|
||||
<link rel="stylesheet" href="resource://devtools/client/shared/components/sidebar-toggle.css"/>
|
||||
|
@ -132,60 +131,7 @@
|
|||
|
||||
<div id="computedview-container">
|
||||
<div id="computedview-container-focusable" tabindex="-1">
|
||||
<div id="old-boxmodel-wrapper" tabindex="0"
|
||||
data-localization-bundle="devtools/client/locales/boxmodel.properties">
|
||||
<div id="old-boxmodel-header">
|
||||
<div id="old-boxmodel-expander" class="expander theme-twisty expandable" open=""></div>
|
||||
<span data-localization="content=boxmodel.title"></span>
|
||||
</div>
|
||||
|
||||
<div id="old-boxmodel-container">
|
||||
<div id="old-boxmodel-main">
|
||||
<span class="old-boxmodel-legend" data-box="margin" data-localization="content=boxmodel.margin;title=boxmodel.margin"></span>
|
||||
<div id="old-boxmodel-margins" data-box="margin" data-localization="title=boxmodel.margin">
|
||||
<span class="old-boxmodel-legend" data-box="border" data-localization="content=boxmodel.border;title=boxmodel.border"></span>
|
||||
<div id="old-boxmodel-borders" data-box="border" data-localization="title=boxmodel.border">
|
||||
<span class="old-boxmodel-legend" data-box="padding" data-localization="content=boxmodel.padding;title=boxmodel.padding"></span>
|
||||
<div id="old-boxmodel-padding" data-box="padding" data-localization="title=boxmodel.padding">
|
||||
<div id="old-boxmodel-content" data-box="content" data-localization="title=boxmodel.content">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<p class="old-boxmodel-margin old-boxmodel-top"><span data-box="margin" class="old-boxmodel-editable" title="margin-top"></span></p>
|
||||
<p class="old-boxmodel-margin old-boxmodel-right"><span data-box="margin" class="old-boxmodel-editable" title="margin-right"></span></p>
|
||||
<p class="old-boxmodel-margin old-boxmodel-bottom"><span data-box="margin" class="old-boxmodel-editable" title="margin-bottom"></span></p>
|
||||
<p class="old-boxmodel-margin old-boxmodel-left"><span data-box="margin" class="old-boxmodel-editable" title="margin-left"></span></p>
|
||||
|
||||
<p class="old-boxmodel-border old-boxmodel-top"><span data-box="border" class="old-boxmodel-editable" title="border-top"></span></p>
|
||||
<p class="old-boxmodel-border old-boxmodel-right"><span data-box="border" class="old-boxmodel-editable" title="border-right"></span></p>
|
||||
<p class="old-boxmodel-border old-boxmodel-bottom"><span data-box="border" class="old-boxmodel-editable" title="border-bottom"></span></p>
|
||||
<p class="old-boxmodel-border old-boxmodel-left"><span data-box="border" class="old-boxmodel-editable" title="border-left"></span></p>
|
||||
|
||||
<p class="old-boxmodel-padding old-boxmodel-top"><span data-box="padding" class="old-boxmodel-editable" title="padding-top"></span></p>
|
||||
<p class="old-boxmodel-padding old-boxmodel-right"><span data-box="padding" class="old-boxmodel-editable" title="padding-right"></span></p>
|
||||
<p class="old-boxmodel-padding old-boxmodel-bottom"><span data-box="padding" class="old-boxmodel-editable" title="padding-bottom"></span></p>
|
||||
<p class="old-boxmodel-padding old-boxmodel-left"><span data-box="padding" class="old-boxmodel-editable" title="padding-left"></span></p>
|
||||
|
||||
<p class="old-boxmodel-size">
|
||||
<span data-box="content" data-localization="title=boxmodel.content"></span>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div id="old-boxmodel-info">
|
||||
<span id="old-boxmodel-element-size"></span>
|
||||
<section id="old-boxmodel-position-group">
|
||||
<button class="devtools-button" id="old-layout-geometry-editor"
|
||||
data-localization="title=boxmodel.geometryButton.tooltip"></button>
|
||||
<span id="old-boxmodel-element-position"></span>
|
||||
</section>
|
||||
</div>
|
||||
|
||||
<div style="display: none">
|
||||
<p id="old-boxmodel-dummy"></p>
|
||||
</div>
|
||||
</div>
|
||||
<div id="boxmodel-wrapper" tabindex="0">
|
||||
</div>
|
||||
|
||||
<div id="propertyContainer" class="theme-separator" tabindex="0" dir="ltr">
|
||||
|
|
|
@ -17,9 +17,6 @@ createEnum([
|
|||
// Update the entire grids state with the new list of grids.
|
||||
"UPDATE_GRIDS",
|
||||
|
||||
// Update the layout state with the latest layout properties.
|
||||
"UPDATE_LAYOUT",
|
||||
|
||||
// Update the grid highlighter's show grid line numbers state.
|
||||
"UPDATE_SHOW_GRID_LINE_NUMBERS",
|
||||
|
||||
|
|
|
@ -5,7 +5,6 @@
|
|||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
DevToolsModules(
|
||||
'box-model.js',
|
||||
'grids.js',
|
||||
'highlighter-settings.js',
|
||||
'index.js',
|
||||
|
|
|
@ -11,9 +11,10 @@ const { connect } = require("devtools/client/shared/vendor/react-redux");
|
|||
const { LocalizationHelper } = require("devtools/shared/l10n");
|
||||
|
||||
const Accordion = createFactory(require("./Accordion"));
|
||||
const BoxModel = createFactory(require("./BoxModel"));
|
||||
const Grid = createFactory(require("./Grid"));
|
||||
|
||||
const BoxModel = createFactory(require("devtools/client/inspector/boxmodel/components/BoxModel"));
|
||||
|
||||
const Types = require("../types");
|
||||
const { getStr } = require("../utils/l10n");
|
||||
|
||||
|
|
|
@ -8,12 +8,6 @@ DevToolsModules(
|
|||
'Accordion.css',
|
||||
'Accordion.js',
|
||||
'App.js',
|
||||
'BoxModel.js',
|
||||
'BoxModelEditable.js',
|
||||
'BoxModelInfo.js',
|
||||
'BoxModelMain.js',
|
||||
'BoxModelProperties.js',
|
||||
'ComputedProperty.js',
|
||||
'Grid.js',
|
||||
'GridDisplaySettings.js',
|
||||
'GridItem.js',
|
||||
|
|
|
@ -6,18 +6,12 @@
|
|||
|
||||
const Services = require("Services");
|
||||
const { Task } = require("devtools/shared/task");
|
||||
const { getCssProperties } = require("devtools/shared/fronts/css-properties");
|
||||
const { ReflowFront } = require("devtools/shared/fronts/reflow");
|
||||
|
||||
const { InplaceEditor } = require("devtools/client/shared/inplace-editor");
|
||||
const { createFactory, createElement } = require("devtools/client/shared/vendor/react");
|
||||
const { Provider } = require("devtools/client/shared/vendor/react-redux");
|
||||
|
||||
const SwatchColorPickerTooltip = require("devtools/client/shared/widgets/tooltip/SwatchColorPickerTooltip");
|
||||
|
||||
const {
|
||||
updateLayout,
|
||||
} = require("./actions/box-model");
|
||||
const {
|
||||
updateGridColor,
|
||||
updateGridHighlighted,
|
||||
|
@ -30,13 +24,10 @@ const {
|
|||
|
||||
const App = createFactory(require("./components/App"));
|
||||
|
||||
const EditingSession = require("./utils/editing-session");
|
||||
|
||||
const { LocalizationHelper } = require("devtools/shared/l10n");
|
||||
const INSPECTOR_L10N =
|
||||
new LocalizationHelper("devtools/client/locales/inspector.properties");
|
||||
|
||||
const NUMERIC = /^-?[\d\.]+$/;
|
||||
const SHOW_GRID_LINE_NUMBERS = "devtools.gridinspector.showGridLineNumbers";
|
||||
const SHOW_INFINITE_LINES_PREF = "devtools.gridinspector.showInfiniteLines";
|
||||
|
||||
|
@ -59,11 +50,8 @@ function LayoutView(inspector, window) {
|
|||
this.store = inspector.store;
|
||||
this.walker = this.inspector.walker;
|
||||
|
||||
this.updateBoxModel = this.updateBoxModel.bind(this);
|
||||
|
||||
this.onGridLayoutChange = this.onGridLayoutChange.bind(this);
|
||||
this.onHighlighterChange = this.onHighlighterChange.bind(this);
|
||||
this.onNewSelection = this.onNewSelection.bind(this);
|
||||
this.onSidebarSelect = this.onSidebarSelect.bind(this);
|
||||
|
||||
this.init();
|
||||
|
@ -80,13 +68,18 @@ LayoutView.prototype = {
|
|||
return;
|
||||
}
|
||||
|
||||
let {
|
||||
onHideBoxModelHighlighter,
|
||||
onShowBoxModelEditor,
|
||||
onShowBoxModelHighlighter,
|
||||
} = this.inspector.boxmodel.getComponentProps();
|
||||
|
||||
this.layoutInspector = yield this.inspector.walker.getLayoutInspector();
|
||||
|
||||
this.loadHighlighterSettings();
|
||||
|
||||
this.highlighters.on("grid-highlighter-hidden", this.onHighlighterChange);
|
||||
this.highlighters.on("grid-highlighter-shown", this.onHighlighterChange);
|
||||
this.inspector.selection.on("new-node-front", this.onNewSelection);
|
||||
this.inspector.sidebar.on("select", this.onSidebarSelect);
|
||||
|
||||
// Create a shared SwatchColorPicker instance to be reused by all GridItem components.
|
||||
|
@ -112,13 +105,9 @@ LayoutView.prototype = {
|
|||
*/
|
||||
showBoxModelProperties: true,
|
||||
|
||||
/**
|
||||
* Hides the box-model highlighter on the currently selected element.
|
||||
*/
|
||||
onHideBoxModelHighlighter: () => {
|
||||
let toolbox = this.inspector.toolbox;
|
||||
toolbox.highlighterUtils.unhighlight();
|
||||
},
|
||||
onHideBoxModelHighlighter,
|
||||
onShowBoxModelEditor,
|
||||
onShowBoxModelHighlighter,
|
||||
|
||||
/**
|
||||
* Handler for a change in the grid overlay color picker for a grid container.
|
||||
|
@ -143,88 +132,6 @@ LayoutView.prototype = {
|
|||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Shows the inplace editor when a box model editable value is clicked on the
|
||||
* box model panel.
|
||||
*
|
||||
* @param {DOMNode} element
|
||||
* The element that was clicked.
|
||||
* @param {Event} event
|
||||
* The event object.
|
||||
* @param {String} property
|
||||
* The name of the property.
|
||||
*/
|
||||
onShowBoxModelEditor: (element, event, property) => {
|
||||
let session = new EditingSession({
|
||||
inspector: this.inspector,
|
||||
doc: this.document,
|
||||
elementRules: this.elementRules,
|
||||
});
|
||||
let initialValue = session.getProperty(property);
|
||||
|
||||
let editor = new InplaceEditor({
|
||||
element: element,
|
||||
initial: initialValue,
|
||||
contentType: InplaceEditor.CONTENT_TYPES.CSS_VALUE,
|
||||
property: {
|
||||
name: property
|
||||
},
|
||||
start: self => {
|
||||
self.elt.parentNode.classList.add("boxmodel-editing");
|
||||
},
|
||||
change: value => {
|
||||
if (NUMERIC.test(value)) {
|
||||
value += "px";
|
||||
}
|
||||
|
||||
let properties = [
|
||||
{ name: property, value: value }
|
||||
];
|
||||
|
||||
if (property.substring(0, 7) == "border-") {
|
||||
let bprop = property.substring(0, property.length - 5) + "style";
|
||||
let style = session.getProperty(bprop);
|
||||
if (!style || style == "none" || style == "hidden") {
|
||||
properties.push({ name: bprop, value: "solid" });
|
||||
}
|
||||
}
|
||||
|
||||
session.setProperties(properties).catch(e => console.error(e));
|
||||
},
|
||||
done: (value, commit) => {
|
||||
editor.elt.parentNode.classList.remove("boxmodel-editing");
|
||||
if (!commit) {
|
||||
session.revert().then(() => {
|
||||
session.destroy();
|
||||
}, e => console.error(e));
|
||||
return;
|
||||
}
|
||||
|
||||
let node = this.inspector.selection.nodeFront;
|
||||
this.inspector.pageStyle.getLayout(node, {
|
||||
autoMargins: true,
|
||||
}).then(layout => {
|
||||
this.store.dispatch(updateLayout(layout));
|
||||
}, e => console.error(e));
|
||||
},
|
||||
contextMenu: this.inspector.onTextBoxContextMenu,
|
||||
cssProperties: getCssProperties(this.inspector.toolbox)
|
||||
}, event);
|
||||
},
|
||||
|
||||
/**
|
||||
* Shows the box-model highlighter on the currently selected element.
|
||||
*
|
||||
* @param {Object} options
|
||||
* Options passed to the highlighter actor.
|
||||
*/
|
||||
onShowBoxModelHighlighter: (options = {}) => {
|
||||
let toolbox = this.inspector.toolbox;
|
||||
let nodeFront = this.inspector.selection.nodeFront;
|
||||
|
||||
toolbox.highlighterUtils.highlightNodeFront(nodeFront, options);
|
||||
},
|
||||
|
||||
/**
|
||||
* Handler for a change in the input checkboxes in the GridList component.
|
||||
* Toggles on/off the grid highlighter for the provided grid container element.
|
||||
|
@ -309,16 +216,9 @@ LayoutView.prototype = {
|
|||
destroy() {
|
||||
this.highlighters.off("grid-highlighter-hidden", this.onHighlighterChange);
|
||||
this.highlighters.off("grid-highlighter-shown", this.onHighlighterChange);
|
||||
this.inspector.selection.off("new-node-front", this.onNewSelection);
|
||||
this.inspector.sidebar.off("select", this.onSidebarSelect);
|
||||
this.layoutInspector.off("grid-layout-changed", this.onGridLayoutChange);
|
||||
|
||||
if (this.reflowFront) {
|
||||
this.untrackReflows();
|
||||
this.reflowFront.destroy();
|
||||
this.reflowFront = null;
|
||||
}
|
||||
|
||||
this.document = null;
|
||||
this.inspector = null;
|
||||
this.layoutInspector = null;
|
||||
|
@ -372,16 +272,6 @@ LayoutView.prototype = {
|
|||
this.inspector.sidebar.getCurrentTabID() === "layoutview";
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns true if the layout panel is visible and the current node is valid to
|
||||
* be displayed in the view.
|
||||
*/
|
||||
isPanelVisibleAndNodeValid() {
|
||||
return this.isPanelVisible() &&
|
||||
this.inspector.selection.isConnected() &&
|
||||
this.inspector.selection.isElementNode();
|
||||
},
|
||||
|
||||
/**
|
||||
* Load the grid highligher display settings into the store from the stored preferences.
|
||||
*/
|
||||
|
@ -395,72 +285,6 @@ LayoutView.prototype = {
|
|||
dispatch(updateShowInfiniteLines(showInfinteLines));
|
||||
},
|
||||
|
||||
/**
|
||||
* Starts listening to reflows in the current tab.
|
||||
*/
|
||||
trackReflows() {
|
||||
if (!this.reflowFront) {
|
||||
let { target } = this.inspector;
|
||||
if (target.form.reflowActor) {
|
||||
this.reflowFront = ReflowFront(target.client,
|
||||
target.form);
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
this.reflowFront.on("reflows", this.updateBoxModel);
|
||||
this.reflowFront.start();
|
||||
},
|
||||
|
||||
/**
|
||||
* Stops listening to reflows in the current tab.
|
||||
*/
|
||||
untrackReflows() {
|
||||
if (!this.reflowFront) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.reflowFront.off("reflows", this.updateBoxModel);
|
||||
this.reflowFront.stop();
|
||||
},
|
||||
|
||||
/**
|
||||
* Updates the box model panel by dispatching the new layout data.
|
||||
*/
|
||||
updateBoxModel() {
|
||||
let lastRequest = Task.spawn((function* () {
|
||||
if (!(this.isPanelVisible() &&
|
||||
this.inspector.selection.isConnected() &&
|
||||
this.inspector.selection.isElementNode())) {
|
||||
return null;
|
||||
}
|
||||
|
||||
let node = this.inspector.selection.nodeFront;
|
||||
let layout = yield this.inspector.pageStyle.getLayout(node, {
|
||||
autoMargins: true,
|
||||
});
|
||||
let styleEntries = yield this.inspector.pageStyle.getApplied(node, {});
|
||||
this.elementRules = styleEntries.map(e => e.rule);
|
||||
|
||||
// Update the redux store with the latest layout properties and update the box
|
||||
// model view.
|
||||
this.store.dispatch(updateLayout(layout));
|
||||
|
||||
// If a subsequent request has been made, wait for that one instead.
|
||||
if (this._lastRequest != lastRequest) {
|
||||
return this._lastRequest;
|
||||
}
|
||||
|
||||
this._lastRequest = null;
|
||||
|
||||
this.inspector.emit("boxmodel-view-updated");
|
||||
return null;
|
||||
}).bind(this)).catch(console.error);
|
||||
|
||||
this._lastRequest = lastRequest;
|
||||
},
|
||||
|
||||
/**
|
||||
* Updates the grid panel by dispatching the new grid data. This is called when the
|
||||
* layout view becomes visible or the view needs to be updated with new grid data.
|
||||
|
@ -526,17 +350,6 @@ LayoutView.prototype = {
|
|||
this.store.dispatch(updateGridHighlighted(nodeFront, highlighted));
|
||||
},
|
||||
|
||||
/**
|
||||
* Selection 'new-node-front' event handler.
|
||||
*/
|
||||
onNewSelection: function () {
|
||||
if (!this.isPanelVisibleAndNodeValid()) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.updateBoxModel();
|
||||
},
|
||||
|
||||
/**
|
||||
* Handler for the inspector sidebar select event. Starts listening for
|
||||
* "grid-layout-changed" if the layout panel is visible. Otherwise, stop
|
||||
|
@ -546,17 +359,10 @@ LayoutView.prototype = {
|
|||
onSidebarSelect() {
|
||||
if (!this.isPanelVisible()) {
|
||||
this.layoutInspector.off("grid-layout-changed", this.onGridLayoutChange);
|
||||
this.untrackReflows();
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.inspector.selection.isConnected() &&
|
||||
this.inspector.selection.isElementNode()) {
|
||||
this.trackReflows();
|
||||
}
|
||||
|
||||
this.layoutInspector.on("grid-layout-changed", this.onGridLayoutChange);
|
||||
this.updateBoxModel();
|
||||
this.updateGridPanel();
|
||||
},
|
||||
|
||||
|
|
|
@ -5,7 +5,6 @@
|
|||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
DevToolsModules(
|
||||
'box-model.js',
|
||||
'grids.js',
|
||||
'highlighter-settings.js',
|
||||
)
|
||||
|
|
|
@ -6,16 +6,6 @@
|
|||
|
||||
const { PropTypes } = require("devtools/client/shared/vendor/react");
|
||||
|
||||
/**
|
||||
* The box model data for the current selected node.
|
||||
*/
|
||||
exports.boxModel = {
|
||||
|
||||
// The layout information of the current selected node
|
||||
layout: PropTypes.object,
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* A single grid container in the document.
|
||||
*/
|
||||
|
|
|
@ -5,6 +5,5 @@
|
|||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
DevToolsModules(
|
||||
'editing-session.js',
|
||||
'l10n.js',
|
||||
)
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
DIRS += [
|
||||
'boxmodel',
|
||||
'components',
|
||||
'computed',
|
||||
'fonts',
|
||||
|
|
|
@ -7,6 +7,6 @@
|
|||
// This file exposes the Redux reducers of the box model, grid and grid highlighter
|
||||
// settings.
|
||||
|
||||
exports.boxModel = require("devtools/client/inspector/layout/reducers/box-model");
|
||||
exports.boxModel = require("devtools/client/inspector/boxmodel/reducers/box-model");
|
||||
exports.grids = require("devtools/client/inspector/layout/reducers/grids");
|
||||
exports.highlighterSettings = require("devtools/client/inspector/layout/reducers/highlighter-settings");
|
||||
|
|
|
@ -66,7 +66,7 @@ add_task(function* () {
|
|||
|
||||
info("Testing the box-model region");
|
||||
let margin = inspector.panelDoc.querySelector(
|
||||
".old-boxmodel-margin.old-boxmodel-top > span");
|
||||
".boxmodel-margin.boxmodel-top > span");
|
||||
EventUtils.synthesizeMouseAtCenter(margin, {}, inspector.panelWin);
|
||||
yield checkTextBox(inspector.panelDoc.activeElement, toolbox);
|
||||
});
|
||||
|
|
|
@ -52,7 +52,15 @@ var openInspectorSidebarTab = Task.async(function* (id) {
|
|||
let {toolbox, inspector, testActor} = yield openInspector();
|
||||
|
||||
info("Selecting the " + id + " sidebar");
|
||||
|
||||
if (id === "computedview" || id === "layoutview") {
|
||||
// The layout and computed views should wait until the box-model widget is ready.
|
||||
let onBoxModelViewReady = inspector.once("boxmodel-view-updated");
|
||||
inspector.sidebar.select(id);
|
||||
yield onBoxModelViewReady;
|
||||
} else {
|
||||
inspector.sidebar.select(id);
|
||||
}
|
||||
|
||||
return {
|
||||
toolbox,
|
||||
|
|
|
@ -177,7 +177,6 @@ devtools.jar:
|
|||
skin/images/noise.png (themes/images/noise.png)
|
||||
skin/images/dropmarker.svg (themes/images/dropmarker.svg)
|
||||
skin/boxmodel.css (themes/boxmodel.css)
|
||||
skin/deprecated-boxmodel.css (themes/deprecated-boxmodel.css)
|
||||
skin/images/geometry-editor.svg (themes/images/geometry-editor.svg)
|
||||
skin/images/pause.svg (themes/images/pause.svg)
|
||||
skin/images/play.svg (themes/images/play.svg)
|
||||
|
|
|
@ -12,6 +12,8 @@ const Services = devtools.require("Services");
|
|||
const { AppConstants } = devtools.require("resource://gre/modules/AppConstants.jsm");
|
||||
|
||||
const BROWSER_BASED_DIRS = [
|
||||
"resource://devtools/client/inspector/boxmodel",
|
||||
"resource://devtools/client/inspector/computed",
|
||||
"resource://devtools/client/inspector/layout",
|
||||
"resource://devtools/client/jsonview",
|
||||
"resource://devtools/client/shared/vendor",
|
||||
|
|
|
@ -1,259 +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/ */
|
||||
|
||||
/**
|
||||
* THIS STYLESHEET IS FOR THE DEPRECATED BOX MODEL MODULE (deprecated-box-model.js) AND
|
||||
* SHOULD NO LONGER BE MODIFIED.
|
||||
*/
|
||||
|
||||
#old-boxmodel-wrapper {
|
||||
border-bottom-style: solid;
|
||||
border-bottom-width: 1px;
|
||||
border-color: var(--theme-splitter-color);
|
||||
-moz-user-select: none;
|
||||
}
|
||||
|
||||
#old-boxmodel-container {
|
||||
/* The view will grow bigger as the window gets resized, until 400px */
|
||||
max-width: 400px;
|
||||
margin: 0px auto;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
/* Header */
|
||||
|
||||
#old-boxmodel-header,
|
||||
#old-boxmodel-info {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 4px 17px;
|
||||
}
|
||||
|
||||
#old-layout-geometry-editor {
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
#old-layout-geometry-editor::before {
|
||||
background: url(images/geometry-editor.svg) no-repeat center center / 16px 16px;
|
||||
}
|
||||
|
||||
/* Main: contains the box-model regions */
|
||||
|
||||
#old-boxmodel-main {
|
||||
position: relative;
|
||||
box-sizing: border-box;
|
||||
/* The regions are semi-transparent, so the white background is partly
|
||||
visible */
|
||||
background-color: white;
|
||||
color: var(--theme-selection-color);
|
||||
/* Make sure there is some space between the window's edges and the regions */
|
||||
margin: 0 14px 4px 14px;
|
||||
width: calc(100% - 2 * 14px);
|
||||
}
|
||||
|
||||
.old-boxmodel-margin,
|
||||
.old-boxmodel-size {
|
||||
color: var(--theme-highlight-blue);
|
||||
}
|
||||
|
||||
/* Regions are 3 nested elements with wide borders and outlines */
|
||||
|
||||
#old-boxmodel-content {
|
||||
height: 18px;
|
||||
}
|
||||
|
||||
#old-boxmodel-margins,
|
||||
#old-boxmodel-borders,
|
||||
#old-boxmodel-padding {
|
||||
border-color: hsla(210,100%,85%,0.2);
|
||||
border-width: 18px;
|
||||
border-style: solid;
|
||||
outline: dotted 1px hsl(210,100%,85%);
|
||||
}
|
||||
|
||||
#old-boxmodel-margins {
|
||||
/* This opacity applies to all of the regions, since they are nested */
|
||||
opacity: .8;
|
||||
}
|
||||
|
||||
/* Regions colors */
|
||||
|
||||
#old-boxmodel-margins {
|
||||
border-color: #edff64;
|
||||
}
|
||||
|
||||
#old-boxmodel-borders {
|
||||
border-color: #444444;
|
||||
}
|
||||
|
||||
#old-boxmodel-padding {
|
||||
border-color: #6a5acd;
|
||||
}
|
||||
|
||||
#old-boxmodel-content {
|
||||
background-color: #87ceeb;
|
||||
}
|
||||
|
||||
.theme-firebug #old-boxmodel-main,
|
||||
.theme-firebug #old-boxmodel-borders,
|
||||
.theme-firebug #old-boxmodel-content {
|
||||
border-style: solid;
|
||||
}
|
||||
|
||||
.theme-firebug #old-boxmodel-main,
|
||||
.theme-firebug #old-boxmodel-header {
|
||||
font-family: var(--proportional-font-family);
|
||||
}
|
||||
|
||||
.theme-firebug #old-boxmodel-main {
|
||||
color: var(--theme-body-color);
|
||||
font-size: var(--theme-toolbar-font-size);
|
||||
}
|
||||
|
||||
.theme-firebug #old-boxmodel-header {
|
||||
font-size: var(--theme-toolbar-font-size);
|
||||
}
|
||||
|
||||
/* Editable region sizes are contained in absolutely positioned <p> */
|
||||
|
||||
#old-boxmodel-main > p {
|
||||
position: absolute;
|
||||
pointer-events: none;
|
||||
margin: 0;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
#old-boxmodel-main > p > span,
|
||||
#old-boxmodel-main > p > input {
|
||||
vertical-align: middle;
|
||||
pointer-events: auto;
|
||||
}
|
||||
|
||||
/* Coordinates for the region sizes */
|
||||
|
||||
.old-boxmodel-top,
|
||||
.old-boxmodel-bottom {
|
||||
width: calc(100% - 2px);
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.old-boxmodel-padding.old-boxmodel-top {
|
||||
top: 37px;
|
||||
}
|
||||
|
||||
.old-boxmodel-padding.old-boxmodel-bottom {
|
||||
bottom: 38px;
|
||||
}
|
||||
|
||||
.old-boxmodel-border.old-boxmodel-top {
|
||||
top: 19px;
|
||||
}
|
||||
|
||||
.old-boxmodel-border.old-boxmodel-bottom {
|
||||
bottom: 20px;
|
||||
}
|
||||
|
||||
.old-boxmodel-margin.old-boxmodel-top {
|
||||
top: 1px;
|
||||
}
|
||||
|
||||
.old-boxmodel-margin.old-boxmodel-bottom {
|
||||
bottom: 2px;
|
||||
}
|
||||
|
||||
.old-boxmodel-size,
|
||||
.old-boxmodel-margin.old-boxmodel-left,
|
||||
.old-boxmodel-margin.old-boxmodel-right,
|
||||
.old-boxmodel-border.old-boxmodel-left,
|
||||
.old-boxmodel-border.old-boxmodel-right,
|
||||
.old-boxmodel-padding.old-boxmodel-left,
|
||||
.old-boxmodel-padding.old-boxmodel-right {
|
||||
top: 22px;
|
||||
line-height: 80px;
|
||||
}
|
||||
|
||||
.old-boxmodel-size {
|
||||
width: calc(100% - 2px);
|
||||
}
|
||||
|
||||
.old-boxmodel-margin.old-boxmodel-right,
|
||||
.old-boxmodel-margin.old-boxmodel-left,
|
||||
.old-boxmodel-border.old-boxmodel-left,
|
||||
.old-boxmodel-border.old-boxmodel-right,
|
||||
.old-boxmodel-padding.old-boxmodel-right,
|
||||
.old-boxmodel-padding.old-boxmodel-left {
|
||||
width: 21px;
|
||||
}
|
||||
|
||||
.old-boxmodel-padding.old-boxmodel-left {
|
||||
left: 35px;
|
||||
}
|
||||
|
||||
.old-boxmodel-padding.old-boxmodel-right {
|
||||
right: 35px;
|
||||
}
|
||||
|
||||
.old-boxmodel-border.old-boxmodel-left {
|
||||
left: 16px;
|
||||
}
|
||||
|
||||
.old-boxmodel-border.old-boxmodel-right {
|
||||
right: 17px;
|
||||
}
|
||||
|
||||
.old-boxmodel-margin.old-boxmodel-right {
|
||||
right: 0;
|
||||
}
|
||||
|
||||
.old-boxmodel-margin.old-boxmodel-left {
|
||||
left: 0;
|
||||
}
|
||||
|
||||
.old-boxmodel-rotate.old-boxmodel-left:not(.old-boxmodel-editing) {
|
||||
transform: rotate(-90deg);
|
||||
}
|
||||
|
||||
.old-boxmodel-rotate.old-boxmodel-right:not(.old-boxmodel-editing) {
|
||||
transform: rotate(90deg);
|
||||
}
|
||||
|
||||
/* Legend: displayed inside regions */
|
||||
|
||||
.old-boxmodel-legend {
|
||||
position: absolute;
|
||||
margin: 2px 6px;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.old-boxmodel-legend[data-box="margin"] {
|
||||
color: var(--theme-highlight-blue);
|
||||
}
|
||||
|
||||
/* Editable fields */
|
||||
|
||||
.old-boxmodel-editable {
|
||||
border: 1px dashed transparent;
|
||||
-moz-user-select: none;
|
||||
}
|
||||
|
||||
.old-boxmodel-editable:hover {
|
||||
border-bottom-color: hsl(0, 0%, 50%);
|
||||
}
|
||||
|
||||
/* Make sure the content size doesn't appear as editable like the other sizes */
|
||||
|
||||
.old-boxmodel-size > span {
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
/* Box Model Info: contains the position and size of the element */
|
||||
|
||||
#old-boxmodel-element-size {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
#old-boxmodel-position-group {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
|
@ -8,13 +8,9 @@
|
|||
var gDebuggee;
|
||||
var gClient;
|
||||
var gThreadClient;
|
||||
var gOldPref;
|
||||
|
||||
function run_test()
|
||||
{
|
||||
gOldPref = Services.prefs.getBoolPref("javascript.options.wasm");
|
||||
Services.prefs.setBoolPref("javascript.options.wasm", true);
|
||||
|
||||
if (typeof WebAssembly == "undefined") {
|
||||
return; // wasm is not enabled for this platform
|
||||
}
|
||||
|
@ -49,7 +45,6 @@ function test_pause_frame()
|
|||
do_check_eq(location.column > 0, true);
|
||||
do_check_eq(location.source.url.endsWith(" > wasm"), true);
|
||||
|
||||
Services.prefs.setBoolPref("javascript.options.wasm", gOldPref);
|
||||
finishClient(gClient);
|
||||
});
|
||||
});
|
||||
|
@ -58,7 +53,7 @@ function test_pause_frame()
|
|||
// WebAssembly bytecode was generated by running:
|
||||
// js -e 'print(wasmTextToBinary("(module(import \"a\" \"b\")(func(export \"c\")call 0))"))'
|
||||
var m = new WebAssembly.Module(new Uint8Array([
|
||||
0,97,115,109,13,0,0,0,1,132,128,128,128,0,1,96,0,0,2,135,128,128,128,0,1,1,97,1,
|
||||
0,97,115,109,1,0,0,0,1,132,128,128,128,0,1,96,0,0,2,135,128,128,128,0,1,1,97,1,
|
||||
98,0,0,3,130,128,128,128,0,1,0,6,129,128,128,128,0,0,7,133,128,128,128,0,1,1,99,
|
||||
0,1,10,138,128,128,128,0,1,132,128,128,128,0,0,16,0,11
|
||||
]));
|
||||
|
|
|
@ -172,7 +172,7 @@ NS_INTERFACE_MAP_END
|
|||
CustomElementRegistry::IsCustomElementEnabled(JSContext* aCx, JSObject* aObject)
|
||||
{
|
||||
return Preferences::GetBool("dom.webcomponents.customelements.enabled") ||
|
||||
Preferences::GetBool("dom.webcomponents.enabled");
|
||||
nsContentUtils::IsWebComponentsEnabled();
|
||||
}
|
||||
|
||||
/* static */ already_AddRefed<CustomElementRegistry>
|
||||
|
|
|
@ -285,6 +285,7 @@ bool nsContentUtils::sIsPerformanceTimingEnabled = false;
|
|||
bool nsContentUtils::sIsResourceTimingEnabled = false;
|
||||
bool nsContentUtils::sIsUserTimingLoggingEnabled = false;
|
||||
bool nsContentUtils::sIsExperimentalAutocompleteEnabled = false;
|
||||
bool nsContentUtils::sIsWebComponentsEnabled = false;
|
||||
bool nsContentUtils::sEncodeDecodeURLHash = false;
|
||||
bool nsContentUtils::sGettersDecodeURLHash = false;
|
||||
bool nsContentUtils::sPrivacyResistFingerprinting = false;
|
||||
|
@ -512,10 +513,11 @@ nsContentUtils::Init()
|
|||
sSecurityManager->GetSystemPrincipal(&sSystemPrincipal);
|
||||
MOZ_ASSERT(sSystemPrincipal);
|
||||
|
||||
// We use the constructor here because we want infallible initialization; we
|
||||
// apparently don't care whether sNullSubjectPrincipal has a sane URI or not.
|
||||
RefPtr<nsNullPrincipal> nullPrincipal = new nsNullPrincipal();
|
||||
nullPrincipal->Init();
|
||||
RefPtr<nsNullPrincipal> nullPrincipal = nsNullPrincipal::Create();
|
||||
if (!nullPrincipal) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
nullPrincipal.forget(&sNullSubjectPrincipal);
|
||||
|
||||
nsresult rv = CallGetService(NS_IOSERVICE_CONTRACTID, &sIOService);
|
||||
|
@ -582,6 +584,9 @@ nsContentUtils::Init()
|
|||
Preferences::AddBoolVarCache(&sIsExperimentalAutocompleteEnabled,
|
||||
"dom.forms.autocomplete.experimental", false);
|
||||
|
||||
Preferences::AddBoolVarCache(&sIsWebComponentsEnabled,
|
||||
"dom.webcomponents.enabled", false);
|
||||
|
||||
Preferences::AddBoolVarCache(&sEncodeDecodeURLHash,
|
||||
"dom.url.encode_decode_hash", false);
|
||||
|
||||
|
|
|
@ -2806,6 +2806,9 @@ public:
|
|||
const mozilla::dom::Sequence<JSObject*>& aTransfer,
|
||||
JS::MutableHandle<JS::Value> aValue);
|
||||
|
||||
static bool
|
||||
IsWebComponentsEnabled() { return sIsWebComponentsEnabled; }
|
||||
|
||||
private:
|
||||
static bool InitializeEventTable();
|
||||
|
||||
|
@ -2912,6 +2915,7 @@ private:
|
|||
static bool sIsUserTimingLoggingEnabled;
|
||||
static bool sIsFrameTimingPrefEnabled;
|
||||
static bool sIsExperimentalAutocompleteEnabled;
|
||||
static bool sIsWebComponentsEnabled;
|
||||
static bool sEncodeDecodeURLHash;
|
||||
static bool sGettersDecodeURLHash;
|
||||
static bool sPrivacyResistFingerprinting;
|
||||
|
|
|
@ -104,6 +104,7 @@
|
|||
#include "nsIScriptSecurityManager.h"
|
||||
#include "nsIPermissionManager.h"
|
||||
#include "nsIPrincipal.h"
|
||||
#include "nsNullPrincipal.h"
|
||||
|
||||
#include "nsIDOMWindow.h"
|
||||
#include "nsPIDOMWindow.h"
|
||||
|
@ -2736,7 +2737,7 @@ nsDocument::InitCSP(nsIChannel* aChannel)
|
|||
if (cspSandboxFlags & SANDBOXED_ORIGIN) {
|
||||
// If the new CSP sandbox flags do not have the allow-same-origin flag
|
||||
// reset the document principal to a null principal
|
||||
principal = do_CreateInstance("@mozilla.org/nullprincipal;1");
|
||||
principal = nsNullPrincipal::Create();
|
||||
SetPrincipal(principal);
|
||||
}
|
||||
|
||||
|
@ -5941,7 +5942,7 @@ nsDocument::IsWebComponentsEnabled(JSContext* aCx, JSObject* aObject)
|
|||
{
|
||||
JS::Rooted<JSObject*> obj(aCx, aObject);
|
||||
|
||||
if (Preferences::GetBool("dom.webcomponents.enabled")) {
|
||||
if (nsContentUtils::IsWebComponentsEnabled()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -5957,7 +5958,7 @@ nsDocument::IsWebComponentsEnabled(JSContext* aCx, JSObject* aObject)
|
|||
bool
|
||||
nsDocument::IsWebComponentsEnabled(dom::NodeInfo* aNodeInfo)
|
||||
{
|
||||
if (Preferences::GetBool("dom.webcomponents.enabled")) {
|
||||
if (nsContentUtils::IsWebComponentsEnabled()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -9406,21 +9406,16 @@ public:
|
|||
nsAutoString addonId;
|
||||
if (NS_SUCCEEDED(pc->GetAddonId(addonId)) && !addonId.IsEmpty()) {
|
||||
// We want to nuke all references to the add-on compartment.
|
||||
js::NukeCrossCompartmentWrappers(cx, js::AllCompartments(),
|
||||
js::SingleCompartment(cpt),
|
||||
xpc::NukeAllWrappersForCompartment(cx, cpt,
|
||||
win->IsInnerWindow() ? js::DontNukeWindowReferences
|
||||
: js::NukeWindowReferences);
|
||||
|
||||
// Now mark the compartment as nuked and non-scriptable.
|
||||
auto compartmentPrivate = xpc::CompartmentPrivate::Get(cpt);
|
||||
compartmentPrivate->wasNuked = true;
|
||||
compartmentPrivate->scriptability.Block();
|
||||
} else {
|
||||
// We only want to nuke wrappers for the chrome->content case
|
||||
js::NukeCrossCompartmentWrappers(cx, BrowserCompartmentMatcher(),
|
||||
js::SingleCompartment(cpt),
|
||||
win->IsInnerWindow() ? js::DontNukeWindowReferences
|
||||
: js::NukeWindowReferences);
|
||||
: js::NukeWindowReferences,
|
||||
js::NukeIncomingReferences);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,8 +11,7 @@
|
|||
<script type="application/javascript;version=1.7">
|
||||
|
||||
function setup_tests() {
|
||||
SpecialPowers.pushPrefEnv({"set": [["dom.input.dirpicker", true],
|
||||
["javascript.options.wasm", true]]}, next);
|
||||
SpecialPowers.pushPrefEnv({"set": [["dom.input.dirpicker", true]]}, next);
|
||||
}
|
||||
|
||||
function getType(a) {
|
||||
|
|
|
@ -1906,11 +1906,7 @@ CanvasRenderingContext2D::GetHeight() const
|
|||
NS_IMETHODIMP
|
||||
CanvasRenderingContext2D::SetDimensions(int32_t aWidth, int32_t aHeight)
|
||||
{
|
||||
bool retainBuffer = false;
|
||||
if (aWidth == mWidth && aHeight == mHeight) {
|
||||
retainBuffer = true;
|
||||
}
|
||||
ClearTarget(retainBuffer);
|
||||
ClearTarget();
|
||||
|
||||
// Zero sized surfaces can cause problems.
|
||||
mZero = false;
|
||||
|
@ -1929,23 +1925,10 @@ CanvasRenderingContext2D::SetDimensions(int32_t aWidth, int32_t aHeight)
|
|||
}
|
||||
|
||||
void
|
||||
CanvasRenderingContext2D::ClearTarget(bool aRetainBuffer)
|
||||
CanvasRenderingContext2D::ClearTarget()
|
||||
{
|
||||
RefPtr<PersistentBufferProvider> provider = mBufferProvider;
|
||||
if (aRetainBuffer && provider) {
|
||||
// We should reset the buffer data before reusing the buffer.
|
||||
if (mTarget) {
|
||||
mTarget->SetTransform(Matrix());
|
||||
}
|
||||
ClearRect(0, 0, mWidth, mHeight);
|
||||
}
|
||||
|
||||
Reset();
|
||||
|
||||
if (aRetainBuffer) {
|
||||
mBufferProvider = provider;
|
||||
}
|
||||
|
||||
mResetLayer = true;
|
||||
|
||||
SetInitialState();
|
||||
|
|
|
@ -682,7 +682,7 @@ protected:
|
|||
/**
|
||||
* Disposes an old target and prepares to lazily create a new target.
|
||||
*/
|
||||
void ClearTarget(bool aRetainBuffer = false);
|
||||
void ClearTarget();
|
||||
|
||||
/*
|
||||
* Returns the target to the buffer provider. i.e. this will queue a frame for
|
||||
|
|
|
@ -544,9 +544,8 @@ GetDOMFileOrDirectoryPath(const OwningFileOrDirectory& aData,
|
|||
bool
|
||||
HTMLInputElement::ValueAsDateEnabled(JSContext* cx, JSObject* obj)
|
||||
{
|
||||
return Preferences::GetBool("dom.experimental_forms", false) ||
|
||||
Preferences::GetBool("dom.forms.datepicker", false) ||
|
||||
Preferences::GetBool("dom.forms.datetime", false);
|
||||
return IsExperimentalFormsEnabled() || IsDatePickerEnabled() ||
|
||||
IsInputDateTimeEnabled();
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
@ -629,7 +628,7 @@ HTMLInputElement::nsFilePickerShownCallback::Done(int16_t aResult)
|
|||
RefPtr<DispatchChangeEventCallback> dispatchChangeEventCallback =
|
||||
new DispatchChangeEventCallback(mInput);
|
||||
|
||||
if (Preferences::GetBool("dom.webkitBlink.dirPicker.enabled", false) &&
|
||||
if (IsWebkitDirPickerEnabled() &&
|
||||
mInput->HasAttr(kNameSpaceID_None, nsGkAtoms::webkitdirectory)) {
|
||||
ErrorResult error;
|
||||
GetFilesHelper* helper = mInput->GetOrCreateGetFilesHelper(true, error);
|
||||
|
@ -830,7 +829,7 @@ HTMLInputElement::IsPopupBlocked() const
|
|||
nsresult
|
||||
HTMLInputElement::InitDatePicker()
|
||||
{
|
||||
if (!Preferences::GetBool("dom.forms.datepicker", false)) {
|
||||
if (!IsDatePickerEnabled()) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -2568,10 +2567,8 @@ bool
|
|||
HTMLInputElement::IsExperimentalMobileType(uint8_t aType)
|
||||
{
|
||||
return (aType == NS_FORM_INPUT_DATE &&
|
||||
!Preferences::GetBool("dom.forms.datetime", false) &&
|
||||
!Preferences::GetBool("dom.forms.datepicker", false)) ||
|
||||
(aType == NS_FORM_INPUT_TIME &&
|
||||
!Preferences::GetBool("dom.forms.datetime", false));
|
||||
!IsInputDateTimeEnabled() && !IsDatePickerEnabled()) ||
|
||||
(aType == NS_FORM_INPUT_TIME && !IsInputDateTimeEnabled());
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -3020,8 +3017,8 @@ HTMLInputElement::GetDisplayFileName(nsAString& aValue) const
|
|||
nsXPIDLString value;
|
||||
|
||||
if (mFilesOrDirectories.IsEmpty()) {
|
||||
if ((Preferences::GetBool("dom.input.dirpicker", false) && Allowdirs()) ||
|
||||
(Preferences::GetBool("dom.webkitBlink.dirPicker.enabled", false) &&
|
||||
if ((IsDirPickerEnabled() && Allowdirs()) ||
|
||||
(IsWebkitDirPickerEnabled() &&
|
||||
HasAttr(kNameSpaceID_None, nsGkAtoms::webkitdirectory))) {
|
||||
nsContentUtils::GetLocalizedString(nsContentUtils::eFORMS_PROPERTIES,
|
||||
"NoDirSelected", value);
|
||||
|
@ -3050,7 +3047,7 @@ HTMLInputElement::SetFilesOrDirectories(const nsTArray<OwningFileOrDirectory>& a
|
|||
{
|
||||
ClearGetFilesHelpers();
|
||||
|
||||
if (Preferences::GetBool("dom.webkitBlink.filesystem.enabled", false)) {
|
||||
if (IsWebkitFileSystemEnabled()) {
|
||||
HTMLInputElementBinding::ClearCachedWebkitEntriesValue(this);
|
||||
mEntries.Clear();
|
||||
}
|
||||
|
@ -3069,7 +3066,7 @@ HTMLInputElement::SetFiles(nsIDOMFileList* aFiles,
|
|||
mFilesOrDirectories.Clear();
|
||||
ClearGetFilesHelpers();
|
||||
|
||||
if (Preferences::GetBool("dom.webkitBlink.filesystem.enabled", false)) {
|
||||
if (IsWebkitFileSystemEnabled()) {
|
||||
HTMLInputElementBinding::ClearCachedWebkitEntriesValue(this);
|
||||
mEntries.Clear();
|
||||
}
|
||||
|
@ -3092,14 +3089,14 @@ HTMLInputElement::MozSetDndFilesAndDirectories(const nsTArray<OwningFileOrDirect
|
|||
{
|
||||
SetFilesOrDirectories(aFilesOrDirectories, true);
|
||||
|
||||
if (Preferences::GetBool("dom.webkitBlink.filesystem.enabled", false)) {
|
||||
if (IsWebkitFileSystemEnabled()) {
|
||||
UpdateEntries(aFilesOrDirectories);
|
||||
}
|
||||
|
||||
RefPtr<DispatchChangeEventCallback> dispatchChangeEventCallback =
|
||||
new DispatchChangeEventCallback(this);
|
||||
|
||||
if (Preferences::GetBool("dom.webkitBlink.dirPicker.enabled", false) &&
|
||||
if (IsWebkitDirPickerEnabled() &&
|
||||
HasAttr(kNameSpaceID_None, nsGkAtoms::webkitdirectory)) {
|
||||
ErrorResult rv;
|
||||
GetFilesHelper* helper = GetOrCreateGetFilesHelper(true /* recursionFlag */,
|
||||
|
@ -3179,8 +3176,8 @@ HTMLInputElement::GetFiles()
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
if (Preferences::GetBool("dom.input.dirpicker", false) && Allowdirs() &&
|
||||
(!Preferences::GetBool("dom.webkitBlink.dirPicker.enabled", false) ||
|
||||
if (IsDirPickerEnabled() && Allowdirs() &&
|
||||
(!IsWebkitDirPickerEnabled() ||
|
||||
!HasAttr(kNameSpaceID_None, nsGkAtoms::webkitdirectory))) {
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -4392,8 +4389,8 @@ HTMLInputElement::MaybeInitPickers(EventChainPostVisitor& aVisitor)
|
|||
do_QueryInterface(aVisitor.mEvent->mOriginalTarget);
|
||||
if (target &&
|
||||
target->FindFirstNonChromeOnlyAccessContent() == this &&
|
||||
((Preferences::GetBool("dom.input.dirpicker", false) && Allowdirs()) ||
|
||||
(Preferences::GetBool("dom.webkitBlink.dirPicker.enabled", false) &&
|
||||
((IsDirPickerEnabled() && Allowdirs()) ||
|
||||
(IsWebkitDirPickerEnabled() &&
|
||||
HasAttr(kNameSpaceID_None, nsGkAtoms::webkitdirectory)))) {
|
||||
type = FILE_PICKER_DIRECTORY;
|
||||
}
|
||||
|
@ -5798,20 +5795,133 @@ HTMLInputElement::ParseTime(const nsAString& aValue, uint32_t* aResult)
|
|||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
IsDateTimeEnabled(int32_t aNewType)
|
||||
/* static */ bool
|
||||
HTMLInputElement::IsDateTimeTypeSupported(uint8_t aDateTimeInputType)
|
||||
{
|
||||
return (aNewType == NS_FORM_INPUT_DATE &&
|
||||
(Preferences::GetBool("dom.forms.datetime", false) ||
|
||||
Preferences::GetBool("dom.experimental_forms", false) ||
|
||||
Preferences::GetBool("dom.forms.datepicker", false))) ||
|
||||
(aNewType == NS_FORM_INPUT_TIME &&
|
||||
(Preferences::GetBool("dom.forms.datetime", false) ||
|
||||
Preferences::GetBool("dom.experimental_forms", false))) ||
|
||||
((aNewType == NS_FORM_INPUT_MONTH ||
|
||||
aNewType == NS_FORM_INPUT_WEEK ||
|
||||
aNewType == NS_FORM_INPUT_DATETIME_LOCAL) &&
|
||||
Preferences::GetBool("dom.forms.datetime", false));
|
||||
return (aDateTimeInputType == NS_FORM_INPUT_DATE &&
|
||||
(IsInputDateTimeEnabled() || IsExperimentalFormsEnabled() ||
|
||||
IsDatePickerEnabled())) ||
|
||||
(aDateTimeInputType == NS_FORM_INPUT_TIME &&
|
||||
(IsInputDateTimeEnabled() || IsExperimentalFormsEnabled())) ||
|
||||
((aDateTimeInputType == NS_FORM_INPUT_MONTH ||
|
||||
aDateTimeInputType == NS_FORM_INPUT_WEEK ||
|
||||
aDateTimeInputType == NS_FORM_INPUT_DATETIME_LOCAL) &&
|
||||
IsInputDateTimeEnabled());
|
||||
}
|
||||
|
||||
/* static */ bool
|
||||
HTMLInputElement::IsWebkitDirPickerEnabled()
|
||||
{
|
||||
static bool sWebkitDirPickerEnabled = false;
|
||||
static bool sWebkitDirPickerPrefCached = false;
|
||||
if (!sWebkitDirPickerPrefCached) {
|
||||
sWebkitDirPickerPrefCached = true;
|
||||
Preferences::AddBoolVarCache(&sWebkitDirPickerEnabled,
|
||||
"dom.webkitBlink.dirPicker.enabled",
|
||||
false);
|
||||
}
|
||||
|
||||
return sWebkitDirPickerEnabled;
|
||||
}
|
||||
|
||||
/* static */ bool
|
||||
HTMLInputElement::IsWebkitFileSystemEnabled()
|
||||
{
|
||||
static bool sWebkitFileSystemEnabled = false;
|
||||
static bool sWebkitFileSystemPrefCached = false;
|
||||
if (!sWebkitFileSystemPrefCached) {
|
||||
sWebkitFileSystemPrefCached = true;
|
||||
Preferences::AddBoolVarCache(&sWebkitFileSystemEnabled,
|
||||
"dom.webkitBlink.filesystem.enabled",
|
||||
false);
|
||||
}
|
||||
|
||||
return sWebkitFileSystemEnabled;
|
||||
}
|
||||
|
||||
/* static */ bool
|
||||
HTMLInputElement::IsDirPickerEnabled()
|
||||
{
|
||||
static bool sDirPickerEnabled = false;
|
||||
static bool sDirPickerPrefCached = false;
|
||||
if (!sDirPickerPrefCached) {
|
||||
sDirPickerPrefCached = true;
|
||||
Preferences::AddBoolVarCache(&sDirPickerEnabled, "dom.input.dirpicker",
|
||||
false);
|
||||
}
|
||||
|
||||
return sDirPickerEnabled;
|
||||
}
|
||||
|
||||
/* static */ bool
|
||||
HTMLInputElement::IsDatePickerEnabled()
|
||||
{
|
||||
static bool sDatePickerEnabled = false;
|
||||
static bool sDatePickerPrefCached = false;
|
||||
if (!sDatePickerPrefCached) {
|
||||
sDatePickerPrefCached = true;
|
||||
Preferences::AddBoolVarCache(&sDatePickerEnabled, "dom.forms.datepicker",
|
||||
false);
|
||||
}
|
||||
|
||||
return sDatePickerEnabled;
|
||||
}
|
||||
|
||||
/* static */ bool
|
||||
HTMLInputElement::IsExperimentalFormsEnabled()
|
||||
{
|
||||
static bool sExperimentalFormsEnabled = false;
|
||||
static bool sExperimentalFormsPrefCached = false;
|
||||
if (!sExperimentalFormsPrefCached) {
|
||||
sExperimentalFormsPrefCached = true;
|
||||
Preferences::AddBoolVarCache(&sExperimentalFormsEnabled,
|
||||
"dom.experimental_forms",
|
||||
false);
|
||||
}
|
||||
|
||||
return sExperimentalFormsEnabled;
|
||||
}
|
||||
|
||||
/* static */ bool
|
||||
HTMLInputElement::IsInputDateTimeEnabled()
|
||||
{
|
||||
static bool sDateTimeEnabled = false;
|
||||
static bool sDateTimePrefCached = false;
|
||||
if (!sDateTimePrefCached) {
|
||||
sDateTimePrefCached = true;
|
||||
Preferences::AddBoolVarCache(&sDateTimeEnabled, "dom.forms.datetime",
|
||||
false);
|
||||
}
|
||||
|
||||
return sDateTimeEnabled;
|
||||
}
|
||||
|
||||
/* static */ bool
|
||||
HTMLInputElement::IsInputNumberEnabled()
|
||||
{
|
||||
static bool sInputNumberEnabled = false;
|
||||
static bool sInputNumberPrefCached = false;
|
||||
if (!sInputNumberPrefCached) {
|
||||
sInputNumberPrefCached = true;
|
||||
Preferences::AddBoolVarCache(&sInputNumberEnabled, "dom.forms.number",
|
||||
false);
|
||||
}
|
||||
|
||||
return sInputNumberEnabled;
|
||||
}
|
||||
|
||||
/* static */ bool
|
||||
HTMLInputElement::IsInputColorEnabled()
|
||||
{
|
||||
static bool sInputColorEnabled = false;
|
||||
static bool sInputColorPrefCached = false;
|
||||
if (!sInputColorPrefCached) {
|
||||
sInputColorPrefCached = true;
|
||||
Preferences::AddBoolVarCache(&sInputColorEnabled, "dom.forms.color",
|
||||
false);
|
||||
}
|
||||
|
||||
return sInputColorEnabled;
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -5829,12 +5939,11 @@ HTMLInputElement::ParseAttribute(int32_t aNamespaceID,
|
|||
if (success) {
|
||||
newType = aResult.GetEnumValue();
|
||||
if ((IsExperimentalMobileType(newType) &&
|
||||
!Preferences::GetBool("dom.experimental_forms", false)) ||
|
||||
(newType == NS_FORM_INPUT_NUMBER &&
|
||||
!Preferences::GetBool("dom.forms.number", false)) ||
|
||||
(newType == NS_FORM_INPUT_COLOR &&
|
||||
!Preferences::GetBool("dom.forms.color", false)) ||
|
||||
(IsDateTimeInputType(newType) && !IsDateTimeEnabled(newType))) {
|
||||
!IsExperimentalFormsEnabled()) ||
|
||||
(newType == NS_FORM_INPUT_NUMBER && !IsInputNumberEnabled()) ||
|
||||
(newType == NS_FORM_INPUT_COLOR && !IsInputColorEnabled()) ||
|
||||
(IsDateTimeInputType(newType) &&
|
||||
!IsDateTimeTypeSupported(newType))) {
|
||||
newType = kInputDefaultType->value;
|
||||
aResult.SetTo(newType, &aValue);
|
||||
}
|
||||
|
|
|
@ -1650,6 +1650,69 @@ private:
|
|||
aType == NS_FORM_INPUT_TIME;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if aDateTimeInputType should be supported based on "dom.forms.datetime",
|
||||
* "dom.forms.datepicker" and "dom.experimental_forms".
|
||||
*/
|
||||
static bool
|
||||
IsDateTimeTypeSupported(uint8_t aDateTimeInputType);
|
||||
|
||||
/**
|
||||
* Checks preference "dom.webkitBlink.dirPicker.enabled" to determine if
|
||||
* webkitdirectory should be supported.
|
||||
*/
|
||||
static bool
|
||||
IsWebkitDirPickerEnabled();
|
||||
|
||||
/**
|
||||
* Checks preference "dom.webkitBlink.filesystem.enabled" to determine if
|
||||
* webkitEntries should be supported.
|
||||
*/
|
||||
static bool
|
||||
IsWebkitFileSystemEnabled();
|
||||
|
||||
/**
|
||||
* Checks preference "dom.input.dirpicker" to determine if file and directory
|
||||
* entries API should be supported.
|
||||
*/
|
||||
static bool
|
||||
IsDirPickerEnabled();
|
||||
|
||||
/**
|
||||
* Checks preference "dom.forms.datepicker" to determine if date picker should
|
||||
* be supported.
|
||||
*/
|
||||
static bool
|
||||
IsDatePickerEnabled();
|
||||
|
||||
/**
|
||||
* Checks preference "dom.experimental_forms" to determine if experimental
|
||||
* implementation of input element should be enabled.
|
||||
*/
|
||||
static bool
|
||||
IsExperimentalFormsEnabled();
|
||||
|
||||
/**
|
||||
* Checks preference "dom.forms.datetime" to determine if input date/time
|
||||
* related types should be supported.
|
||||
*/
|
||||
static bool
|
||||
IsInputDateTimeEnabled();
|
||||
|
||||
/**
|
||||
* Checks preference "dom.forms.number" to determine if input type=number
|
||||
* should be supported.
|
||||
*/
|
||||
static bool
|
||||
IsInputNumberEnabled();
|
||||
|
||||
/**
|
||||
* Checks preference "dom.forms.color" to determine if date/time related
|
||||
* types should be supported.
|
||||
*/
|
||||
static bool
|
||||
IsInputColorEnabled();
|
||||
|
||||
struct nsFilePickerFilter {
|
||||
nsFilePickerFilter()
|
||||
: mFilterMask(0) {}
|
||||
|
|
|
@ -75,8 +75,7 @@ function* testHarnessSteps() {
|
|||
"set": [
|
||||
["dom.indexedDB.testing", true],
|
||||
["dom.indexedDB.experimental", true],
|
||||
["dom.archivereader.enabled", true],
|
||||
["javascript.options.wasm", true]
|
||||
["dom.archivereader.enabled", true]
|
||||
]
|
||||
},
|
||||
nextTestHarnessStep
|
||||
|
|
Двоичные данные
dom/indexedDB/test/unit/wasm_recompile_profile.zip
Двоичные данные
dom/indexedDB/test/unit/wasm_recompile_profile.zip
Двоичный файл не отображается.
|
@ -50,7 +50,6 @@ if (!this.runTest) {
|
|||
|
||||
enableTesting();
|
||||
enableExperimental();
|
||||
enableWasm();
|
||||
}
|
||||
|
||||
Cu.importGlobalProperties(["indexedDB", "Blob", "File", "FileReader"]);
|
||||
|
@ -63,7 +62,6 @@ if (!this.runTest) {
|
|||
function finishTest()
|
||||
{
|
||||
if (SpecialPowers.isMainProcess()) {
|
||||
resetWasm();
|
||||
resetExperimental();
|
||||
resetTesting();
|
||||
|
||||
|
@ -214,16 +212,6 @@ function resetTesting()
|
|||
SpecialPowers.clearUserPref("dom.indexedDB.testing");
|
||||
}
|
||||
|
||||
function enableWasm()
|
||||
{
|
||||
SpecialPowers.setBoolPref("javascript.options.wasm", true);
|
||||
}
|
||||
|
||||
function resetWasm()
|
||||
{
|
||||
SpecialPowers.clearUserPref("javascript.options.wasm");
|
||||
}
|
||||
|
||||
function gc()
|
||||
{
|
||||
Cu.forceGC();
|
||||
|
|
|
@ -6,6 +6,10 @@
|
|||
|
||||
#include "ContentPrefs.h"
|
||||
|
||||
/************************************************************
|
||||
* DO NOT ADD PREFS TO THIS LIST WITHOUT DOM PEER REVIEW *
|
||||
************************************************************/
|
||||
|
||||
const char* mozilla::dom::ContentPrefs::gInitPrefs[] = {
|
||||
"accessibility.monoaudio.enable",
|
||||
"accessibility.mouse_focuses_formcontrol",
|
||||
|
@ -52,6 +56,7 @@ const char* mozilla::dom::ContentPrefs::gInitPrefs[] = {
|
|||
"dom.vibrator.enabled",
|
||||
"dom.vibrator.max_vibrate_list_len",
|
||||
"dom.vibrator.max_vibrate_ms",
|
||||
"dom.webcomponents.enabled",
|
||||
"focusmanager.testmode",
|
||||
"font.size.inflation.disabledInMasterProcess",
|
||||
"font.size.inflation.emPerLine",
|
||||
|
|
|
@ -48,10 +48,12 @@ function tryToCreateNodeOnClosedContext(ctx) {
|
|||
}
|
||||
|
||||
function loadFile(url, callback) {
|
||||
todo(false, "loadFile: " + url);
|
||||
var xhr = new XMLHttpRequest();
|
||||
xhr.open("GET", url, true);
|
||||
xhr.responseType = "arraybuffer";
|
||||
xhr.onload = function() {
|
||||
todo(false, "loadFile: " + url + " calling callback...");
|
||||
callback(xhr.response);
|
||||
};
|
||||
xhr.send();
|
||||
|
|
|
@ -244,7 +244,7 @@ UDPSocketParent::RecvConnect(const UDPAddressInfo& aAddressInfo)
|
|||
nsCOMPtr<nsIEventTarget> thread(NS_GetCurrentThread());
|
||||
Unused <<
|
||||
NS_WARN_IF(NS_FAILED(GetSTSThread()->Dispatch(WrapRunnable(
|
||||
this,
|
||||
RefPtr<UDPSocketParent>(this),
|
||||
&UDPSocketParent::DoConnect,
|
||||
mSocket,
|
||||
thread,
|
||||
|
@ -266,7 +266,7 @@ UDPSocketParent::SendConnectResponse(nsIEventTarget *aThread,
|
|||
{
|
||||
Unused <<
|
||||
NS_WARN_IF(NS_FAILED(aThread->Dispatch(WrapRunnable(
|
||||
this,
|
||||
RefPtr<UDPSocketParent>(this),
|
||||
&UDPSocketParent::DoSendConnectResponse,
|
||||
aAddressInfo),
|
||||
NS_DISPATCH_NORMAL)));
|
||||
|
@ -586,7 +586,7 @@ UDPSocketParent::SendInternalError(nsIEventTarget *aThread,
|
|||
UDPSOCKET_LOG(("SendInternalError: %u", aLineNo));
|
||||
Unused <<
|
||||
NS_WARN_IF(NS_FAILED(aThread->Dispatch(WrapRunnable(
|
||||
this,
|
||||
RefPtr<UDPSocketParent>(this),
|
||||
&UDPSocketParent::FireInternalError,
|
||||
aLineNo),
|
||||
NS_DISPATCH_NORMAL)));
|
||||
|
|
|
@ -167,7 +167,7 @@ function runTest() {
|
|||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
SpecialPowers.pushPrefEnv({"set": [["javascript.options.wasm", true]]}, runTest);
|
||||
runTest();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -74,6 +74,7 @@ var ecmaGlobals =
|
|||
"URIError",
|
||||
"WeakMap",
|
||||
"WeakSet",
|
||||
{name: "WebAssembly", disabled: !SpecialPowers.Cu.getJSTestingFunctions().wasmIsSupported()}
|
||||
];
|
||||
// IMPORTANT: Do not change the list above without review from
|
||||
// a JavaScript Engine peer!
|
||||
|
|
|
@ -476,6 +476,7 @@ private:
|
|||
UniquePtr<PrincipalInfo> mPrincipalInfo;
|
||||
nsCString mCSPHeaderValue;
|
||||
nsCString mCSPReportOnlyHeaderValue;
|
||||
nsCString mReferrerPolicyHeaderValue;
|
||||
};
|
||||
|
||||
NS_IMPL_ISUPPORTS(CacheScriptLoader, nsIStreamLoaderObserver)
|
||||
|
@ -622,6 +623,10 @@ private:
|
|||
MOZ_ASSERT(!loadInfo.mLoadingFinished);
|
||||
loadInfo.mLoadingFinished = true;
|
||||
|
||||
if (IsMainWorkerScript() && NS_SUCCEEDED(aRv)) {
|
||||
MOZ_DIAGNOSTIC_ASSERT(mWorkerPrivate->PrincipalURIMatchesScriptURL());
|
||||
}
|
||||
|
||||
MaybeExecuteFinishedScripts(aIndex);
|
||||
}
|
||||
|
||||
|
@ -1137,8 +1142,18 @@ private:
|
|||
// Store the channel info if needed.
|
||||
mWorkerPrivate->InitChannelInfo(channel);
|
||||
|
||||
// Our final channel principal should match the original principal
|
||||
// in terms of the origin.
|
||||
MOZ_DIAGNOSTIC_ASSERT(mWorkerPrivate->FinalChannelPrincipalIsValid(channel));
|
||||
|
||||
// However, we must still override the principal since the nsIPrincipal
|
||||
// URL may be different due to same-origin redirects. Unfortunately this
|
||||
// URL must exactly match the final worker script URL in order to
|
||||
// properly set the referrer header on fetch/xhr requests. If bug 1340694
|
||||
// is ever fixed this can be removed.
|
||||
rv = mWorkerPrivate->SetPrincipalFromChannel(channel);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// We did inherit CSP in bug 1223647. If we do not already have a CSP, we
|
||||
// should get it from the HTTP headers on the worker script.
|
||||
if (!mWorkerPrivate->GetCSP() && CSPService::sCSPEnabled) {
|
||||
|
@ -1146,6 +1161,9 @@ private:
|
|||
tCspROHeaderValue);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
mWorkerPrivate->SetReferrerPolicyFromHeaderValue(tRPHeaderCValue);
|
||||
|
||||
WorkerPrivate* parent = mWorkerPrivate->GetParent();
|
||||
if (parent) {
|
||||
// XHR Params Allowed
|
||||
|
@ -1153,16 +1171,6 @@ private:
|
|||
}
|
||||
}
|
||||
|
||||
NS_ConvertUTF8toUTF16 tRPHeaderValue(tRPHeaderCValue);
|
||||
// If there's a Referrer-Policy header, apply it.
|
||||
if (!tRPHeaderValue.IsEmpty()) {
|
||||
net::ReferrerPolicy policy =
|
||||
nsContentUtils::GetReferrerPolicyFromHeader(tRPHeaderValue);
|
||||
if (policy != net::RP_Unset) {
|
||||
mWorkerPrivate->SetReferrerPolicy(policy);
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -1172,7 +1180,8 @@ private:
|
|||
const mozilla::dom::ChannelInfo& aChannelInfo,
|
||||
UniquePtr<PrincipalInfo> aPrincipalInfo,
|
||||
const nsACString& aCSPHeaderValue,
|
||||
const nsACString& aCSPReportOnlyHeaderValue)
|
||||
const nsACString& aCSPReportOnlyHeaderValue,
|
||||
const nsACString& aReferrerPolicyHeaderValue)
|
||||
{
|
||||
AssertIsOnMainThread();
|
||||
MOZ_ASSERT(aIndex < mLoadInfos.Length());
|
||||
|
@ -1230,13 +1239,16 @@ private:
|
|||
// Override the principal on the WorkerPrivate. This is only necessary
|
||||
// in order to get a principal with exactly the correct URL. The fetch
|
||||
// referrer logic depends on the WorkerPrivate principal having a URL
|
||||
// that matches the worker script URL.
|
||||
// that matches the worker script URL. If bug 1340694 is ever fixed
|
||||
// this can be removed.
|
||||
rv = mWorkerPrivate->SetPrincipalOnMainThread(responsePrincipal, loadGroup);
|
||||
MOZ_DIAGNOSTIC_ASSERT(NS_SUCCEEDED(rv));
|
||||
|
||||
rv = mWorkerPrivate->SetCSPFromHeaderValues(aCSPHeaderValue,
|
||||
aCSPReportOnlyHeaderValue);
|
||||
MOZ_DIAGNOSTIC_ASSERT(NS_SUCCEEDED(rv));
|
||||
|
||||
mWorkerPrivate->SetReferrerPolicyFromHeaderValue(aReferrerPolicyHeaderValue);
|
||||
}
|
||||
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
|
@ -1652,6 +1664,8 @@ CacheScriptLoader::ResolvedCallback(JSContext* aCx,
|
|||
mCSPHeaderValue, ignored);
|
||||
headers->Get(NS_LITERAL_CSTRING("content-security-policy-report-only"),
|
||||
mCSPReportOnlyHeaderValue, ignored);
|
||||
headers->Get(NS_LITERAL_CSTRING("referrer-policy"),
|
||||
mReferrerPolicyHeaderValue, ignored);
|
||||
|
||||
nsCOMPtr<nsIInputStream> inputStream;
|
||||
response->GetBody(getter_AddRefs(inputStream));
|
||||
|
@ -1665,7 +1679,8 @@ CacheScriptLoader::ResolvedCallback(JSContext* aCx,
|
|||
mLoadInfo.mCacheStatus = ScriptLoadInfo::Cached;
|
||||
mRunnable->DataReceivedFromCache(mIndex, (uint8_t*)"", 0, mChannelInfo,
|
||||
Move(mPrincipalInfo), mCSPHeaderValue,
|
||||
mCSPReportOnlyHeaderValue);
|
||||
mCSPReportOnlyHeaderValue,
|
||||
mReferrerPolicyHeaderValue);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1726,7 +1741,8 @@ CacheScriptLoader::OnStreamComplete(nsIStreamLoader* aLoader, nsISupports* aCont
|
|||
MOZ_ASSERT(mPrincipalInfo);
|
||||
mRunnable->DataReceivedFromCache(mIndex, aString, aStringLen, mChannelInfo,
|
||||
Move(mPrincipalInfo), mCSPHeaderValue,
|
||||
mCSPReportOnlyHeaderValue);
|
||||
mCSPReportOnlyHeaderValue,
|
||||
mReferrerPolicyHeaderValue);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -1985,6 +1985,57 @@ WorkerLoadInfo::PrincipalIsValid() const
|
|||
mPrincipalInfo->type() != PrincipalInfo::T__None &&
|
||||
mPrincipalInfo->type() <= PrincipalInfo::T__Last;
|
||||
}
|
||||
|
||||
bool
|
||||
WorkerLoadInfo::PrincipalURIMatchesScriptURL()
|
||||
{
|
||||
AssertIsOnMainThread();
|
||||
|
||||
nsAutoCString scheme;
|
||||
nsresult rv = mBaseURI->GetScheme(scheme);
|
||||
NS_ENSURE_SUCCESS(rv, false);
|
||||
|
||||
// A system principal must either be a blob URL or a resource JSM.
|
||||
if (mPrincipal->GetIsSystemPrincipal()) {
|
||||
if (scheme == NS_LITERAL_CSTRING("blob")) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool isResource = false;
|
||||
nsresult rv = NS_URIChainHasFlags(mBaseURI,
|
||||
nsIProtocolHandler::URI_IS_UI_RESOURCE,
|
||||
&isResource);
|
||||
NS_ENSURE_SUCCESS(rv, false);
|
||||
|
||||
return isResource;
|
||||
}
|
||||
|
||||
// A null principal can occur for a data URL worker script or a blob URL
|
||||
// worker script from a sandboxed iframe.
|
||||
if (mPrincipal->GetIsNullPrincipal()) {
|
||||
return scheme == NS_LITERAL_CSTRING("data") ||
|
||||
scheme == NS_LITERAL_CSTRING("blob");
|
||||
}
|
||||
|
||||
// The principal for a blob: URL worker script does not have a matching URL.
|
||||
// This is likely a bug in our referer setting logic, but exempt it for now.
|
||||
// This is another reason we should fix bug 1340694 so that referer does not
|
||||
// depend on the principal URI.
|
||||
if (scheme == NS_LITERAL_CSTRING("blob")) {
|
||||
return true;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIURI> principalURI;
|
||||
rv = mPrincipal->GetURI(getter_AddRefs(principalURI));
|
||||
NS_ENSURE_SUCCESS(rv, false);
|
||||
NS_ENSURE_TRUE(principalURI, false);
|
||||
|
||||
bool equal = false;
|
||||
rv = principalURI->Equals(mBaseURI, &equal);
|
||||
NS_ENSURE_SUCCESS(rv, false);
|
||||
|
||||
return equal;
|
||||
}
|
||||
#endif // defined(DEBUG) || !defined(RELEASE_OR_BETA)
|
||||
|
||||
bool
|
||||
|
@ -2640,6 +2691,26 @@ WorkerPrivateParent<Derived>::SetCSPFromHeaderValues(const nsACString& aCSPHeade
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
template <class Derived>
|
||||
void
|
||||
WorkerPrivateParent<Derived>::SetReferrerPolicyFromHeaderValue(
|
||||
const nsACString& aReferrerPolicyHeaderValue)
|
||||
{
|
||||
NS_ConvertUTF8toUTF16 headerValue(aReferrerPolicyHeaderValue);
|
||||
|
||||
if (headerValue.IsEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
net::ReferrerPolicy policy =
|
||||
nsContentUtils::GetReferrerPolicyFromHeader(headerValue);
|
||||
if (policy == net::RP_Unset) {
|
||||
return;
|
||||
}
|
||||
|
||||
SetReferrerPolicy(policy);
|
||||
}
|
||||
|
||||
|
||||
// Can't use NS_IMPL_CYCLE_COLLECTION_CLASS(WorkerPrivateParent) because of the
|
||||
// templates.
|
||||
|
@ -3869,6 +3940,13 @@ WorkerPrivateParent<Derived>::FinalChannelPrincipalIsValid(nsIChannel* aChannel)
|
|||
{
|
||||
return mLoadInfo.FinalChannelPrincipalIsValid(aChannel);
|
||||
}
|
||||
|
||||
template <class Derived>
|
||||
bool
|
||||
WorkerPrivateParent<Derived>::PrincipalURIMatchesScriptURL()
|
||||
{
|
||||
return mLoadInfo.PrincipalURIMatchesScriptURL();
|
||||
}
|
||||
#endif
|
||||
|
||||
template <class Derived>
|
||||
|
|
|
@ -655,6 +655,9 @@ public:
|
|||
#if defined(DEBUG) || !defined(RELEASE_OR_BETA)
|
||||
bool
|
||||
FinalChannelPrincipalIsValid(nsIChannel* aChannel);
|
||||
|
||||
bool
|
||||
PrincipalURIMatchesScriptURL();
|
||||
#endif
|
||||
|
||||
bool
|
||||
|
@ -703,6 +706,9 @@ public:
|
|||
SetCSPFromHeaderValues(const nsACString& aCSPHeaderValue,
|
||||
const nsACString& aCSPReportOnlyHeaderValue);
|
||||
|
||||
void
|
||||
SetReferrerPolicyFromHeaderValue(const nsACString& aReferrerPolicyHeaderValue);
|
||||
|
||||
net::ReferrerPolicy
|
||||
GetReferrerPolicy() const
|
||||
{
|
||||
|
|
|
@ -296,6 +296,9 @@ struct WorkerLoadInfo
|
|||
|
||||
bool
|
||||
PrincipalIsValid() const;
|
||||
|
||||
bool
|
||||
PrincipalURIMatchesScriptURL();
|
||||
#endif
|
||||
|
||||
bool
|
||||
|
|
|
@ -69,6 +69,7 @@ var ecmaGlobals =
|
|||
"URIError",
|
||||
"WeakMap",
|
||||
"WeakSet",
|
||||
{name: "WebAssembly", optional: true}
|
||||
];
|
||||
// IMPORTANT: Do not change the list above without review from
|
||||
// a JavaScript Engine peer!
|
||||
|
@ -252,6 +253,8 @@ function createInterfaceMap(version, userAgent) {
|
|||
(entry.android === !isAndroid && !entry.nonReleaseAndroid && !entry.nightlyAndroid) ||
|
||||
(entry.release === !isRelease)) {
|
||||
interfaceMap[entry.name] = false;
|
||||
} else if (entry.optional) {
|
||||
interfaceMap[entry.name] = "optional";
|
||||
} else {
|
||||
interfaceMap[entry.name] = true;
|
||||
}
|
||||
|
@ -272,19 +275,23 @@ function runTest(version, userAgent) {
|
|||
if (!/^[A-Z]/.test(name)) {
|
||||
continue;
|
||||
}
|
||||
ok(interfaceMap[name],
|
||||
ok(interfaceMap[name] === "optional" || interfaceMap[name],
|
||||
"If this is failing: DANGER, are you sure you want to expose the new interface " + name +
|
||||
" to all webpages as a property on the service worker? Do not make a change to this file without a " +
|
||||
" review from a DOM peer for that specific change!!! (or a JS peer for changes to ecmaGlobals)");
|
||||
delete interfaceMap[name];
|
||||
}
|
||||
for (var name of Object.keys(interfaceMap)) {
|
||||
if (interfaceMap[name] === "optional") {
|
||||
delete interfaceMap[name];
|
||||
} else {
|
||||
ok(name in self === interfaceMap[name],
|
||||
name + " should " + (interfaceMap[name] ? "" : " NOT") + " be defined on the global scope");
|
||||
if (!interfaceMap[name]) {
|
||||
delete interfaceMap[name];
|
||||
}
|
||||
}
|
||||
}
|
||||
is(Object.keys(interfaceMap).length, 0,
|
||||
"The following interface(s) are not enumerated: " + Object.keys(interfaceMap).join(", "));
|
||||
}
|
||||
|
|
|
@ -69,6 +69,7 @@ var ecmaGlobals =
|
|||
"URIError",
|
||||
"WeakMap",
|
||||
"WeakSet",
|
||||
{name: "WebAssembly", optional: true}
|
||||
];
|
||||
// IMPORTANT: Do not change the list above without review from
|
||||
// a JavaScript Engine peer!
|
||||
|
@ -266,6 +267,8 @@ function createInterfaceMap(version, userAgent) {
|
|||
(entry.release === !isRelease) ||
|
||||
entry.disabled) {
|
||||
interfaceMap[entry.name] = false;
|
||||
} else if (entry.optional) {
|
||||
interfaceMap[entry.name] = "optional";
|
||||
} else {
|
||||
interfaceMap[entry.name] = true;
|
||||
}
|
||||
|
@ -286,19 +289,23 @@ function runTest(version, userAgent) {
|
|||
if (!/^[A-Z]/.test(name)) {
|
||||
continue;
|
||||
}
|
||||
ok(interfaceMap[name],
|
||||
ok(interfaceMap[name] === "optional" || interfaceMap[name],
|
||||
"If this is failing: DANGER, are you sure you want to expose the new interface " + name +
|
||||
" to all webpages as a property on the worker? Do not make a change to this file without a " +
|
||||
" review from a DOM peer for that specific change!!! (or a JS peer for changes to ecmaGlobals)");
|
||||
delete interfaceMap[name];
|
||||
}
|
||||
for (var name of Object.keys(interfaceMap)) {
|
||||
if (interfaceMap[name] === "optional") {
|
||||
delete interfaceMap[name];
|
||||
} else {
|
||||
ok(name in self === interfaceMap[name],
|
||||
name + " should " + (interfaceMap[name] ? "" : " NOT") + " be defined on the global scope");
|
||||
if (!interfaceMap[name]) {
|
||||
delete interfaceMap[name];
|
||||
}
|
||||
}
|
||||
}
|
||||
is(Object.keys(interfaceMap).length, 0,
|
||||
"The following interface(s) are not enumerated: " + Object.keys(interfaceMap).join(", "));
|
||||
}
|
||||
|
|
|
@ -41,10 +41,10 @@ SourceSurfaceSkia::GetFormat() const
|
|||
}
|
||||
|
||||
static sk_sp<SkData>
|
||||
MakeSkData(unsigned char* aData, const IntSize& aSize, int32_t aStride)
|
||||
MakeSkData(void* aData, int32_t aHeight, size_t aStride)
|
||||
{
|
||||
CheckedInt<size_t> size = aStride;
|
||||
size *= aSize.height;
|
||||
size *= aHeight;
|
||||
if (size.isValid()) {
|
||||
void* mem = sk_malloc_flags(size.value(), 0);
|
||||
if (mem) {
|
||||
|
@ -57,13 +57,24 @@ MakeSkData(unsigned char* aData, const IntSize& aSize, int32_t aStride)
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
static sk_sp<SkImage>
|
||||
ReadSkImage(const sk_sp<SkImage>& aImage, const SkImageInfo& aInfo, size_t aStride)
|
||||
{
|
||||
if (sk_sp<SkData> data = MakeSkData(nullptr, aInfo.height(), aStride)) {
|
||||
if (aImage->readPixels(aInfo, data->writable_data(), aStride, 0, 0, SkImage::kDisallow_CachingHint)) {
|
||||
return SkImage::MakeRasterData(aInfo, data, aStride);
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool
|
||||
SourceSurfaceSkia::InitFromData(unsigned char* aData,
|
||||
const IntSize &aSize,
|
||||
int32_t aStride,
|
||||
SurfaceFormat aFormat)
|
||||
{
|
||||
sk_sp<SkData> data = MakeSkData(aData, aSize, aStride);
|
||||
sk_sp<SkData> data = MakeSkData(aData, aSize.height, aStride);
|
||||
if (!data) {
|
||||
return false;
|
||||
}
|
||||
|
@ -125,16 +136,12 @@ SourceSurfaceSkia::InitFromImage(const sk_sp<SkImage>& aImage,
|
|||
uint8_t*
|
||||
SourceSurfaceSkia::GetData()
|
||||
{
|
||||
if (!mImage) {
|
||||
return nullptr;
|
||||
}
|
||||
#ifdef USE_SKIA_GPU
|
||||
if (mImage->isTextureBacked()) {
|
||||
sk_sp<SkImage> raster;
|
||||
if (sk_sp<SkData> data = MakeSkData(nullptr, mSize, mStride)) {
|
||||
SkImageInfo info = MakeSkiaImageInfo(mSize, mFormat);
|
||||
if (mImage->readPixels(info, data->writable_data(), mStride, 0, 0, SkImage::kDisallow_CachingHint)) {
|
||||
raster = SkImage::MakeRasterData(info, data, mStride);
|
||||
}
|
||||
}
|
||||
if (raster) {
|
||||
if (sk_sp<SkImage> raster = ReadSkImage(mImage, MakeSkiaImageInfo(mSize, mFormat), mStride)) {
|
||||
mImage = raster;
|
||||
} else {
|
||||
gfxCriticalError() << "Failed making Skia raster image for GPU surface";
|
||||
|
@ -159,7 +166,7 @@ SourceSurfaceSkia::DrawTargetWillChange()
|
|||
// don't need to do anything for them here.
|
||||
SkPixmap pixmap;
|
||||
if (mImage->peekPixels(&pixmap)) {
|
||||
mImage = SkImage::MakeRasterCopy(pixmap);
|
||||
mImage = ReadSkImage(mImage, pixmap.info(), pixmap.rowBytes());
|
||||
if (!mImage) {
|
||||
gfxCriticalError() << "Failed copying Skia raster snapshot";
|
||||
}
|
||||
|
|
|
@ -104,7 +104,8 @@ public:
|
|||
|
||||
/**
|
||||
* Indicates the buffer is not expected to be shared with any more processes.
|
||||
* May release the handle if possible (see CloseHandleInternal). */
|
||||
* May release the handle if possible (see CloseHandleInternal).
|
||||
*/
|
||||
void FinishedSharing()
|
||||
{
|
||||
MutexAutoLock lock(mMutex);
|
||||
|
@ -112,6 +113,17 @@ public:
|
|||
CloseHandleInternal();
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates whether or not the buffer can be shared with another process
|
||||
* without reallocating. Note that this is racy and should only be used for
|
||||
* informational/reporting purposes.
|
||||
*/
|
||||
bool CanShare() const
|
||||
{
|
||||
MutexAutoLock lock(mMutex);
|
||||
return !mClosed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Allocate a new shared memory buffer so that we can get a new handle for
|
||||
* sharing to new processes. ShareToProcess must have failed with
|
||||
|
@ -150,7 +162,7 @@ private:
|
|||
*/
|
||||
void CloseHandleInternal();
|
||||
|
||||
Mutex mMutex;
|
||||
mutable Mutex mMutex;
|
||||
int32_t mStride;
|
||||
int32_t mMapCount;
|
||||
IntSize mSize;
|
||||
|
|
|
@ -2,7 +2,7 @@ This is the Sanitiser for OpenType project, from http://code.google.com/p/ots/.
|
|||
|
||||
Our reference repository is https://github.com/khaledhosny/ots/.
|
||||
|
||||
Current revision: ba8417620956a920ed1f05a2f666fb6317fb10cb
|
||||
Current revision: ba8417620956a920ed1f05a2f666fb6317fb10cb (5.1.0)
|
||||
|
||||
Upstream files included: LICENSE, src/, include/
|
||||
|
||||
|
|
|
@ -22,7 +22,8 @@ cp -r $1/include .
|
|||
|
||||
echo "Updating README.mozilla..."
|
||||
REVISION=`cd $1; git log | head -1 | sed "s/commit //"`
|
||||
sed -e "s/\(Current revision: \).*/\1$REVISION/" README.mozilla > README.tmp
|
||||
VERSION=`cd $1; git describe | cut -d '-' -f 1 | sed 's/v//'`
|
||||
sed -e "s/\(Current revision: \).*/\1$REVISION \($VERSION\)/" README.mozilla > README.tmp
|
||||
mv README.tmp README.mozilla
|
||||
|
||||
echo "Applying ots-visibility.patch..."
|
||||
|
|
|
@ -461,6 +461,7 @@ private:
|
|||
DECL_GFX_PREF(Live, "layers.advanced.bullet-layers", LayersAllowBulletLayers, bool, false);
|
||||
DECL_GFX_PREF(Live, "layers.advanced.caret-layers", LayersAllowCaretLayers, bool, false);
|
||||
DECL_GFX_PREF(Live, "layers.advanced.boxshadow-outer-layers", LayersAllowOuterBoxShadow, bool, false);
|
||||
DECL_GFX_PREF(Live, "layers.advanced.outline-layers", LayersAllowOutlineLayers, bool, false);
|
||||
DECL_GFX_PREF(Once, "layers.allow-d3d9-fallback", LayersAllowD3D9Fallback, bool, false);
|
||||
DECL_GFX_PREF(Once, "layers.amd-switchable-gfx.enabled", LayersAMDSwitchableGfxEnabled, bool, false);
|
||||
DECL_GFX_PREF(Once, "layers.async-pan-zoom.enabled", AsyncPanZoomEnabledDoNotUseDirectly, bool, true);
|
||||
|
|
|
@ -118,7 +118,8 @@ AnimationSurfaceProvider::LogicalSizeInBytes() const
|
|||
void
|
||||
AnimationSurfaceProvider::AddSizeOfExcludingThis(MallocSizeOf aMallocSizeOf,
|
||||
size_t& aHeapSizeOut,
|
||||
size_t& aNonHeapSizeOut)
|
||||
size_t& aNonHeapSizeOut,
|
||||
size_t& aSharedHandlesOut)
|
||||
{
|
||||
// Note that the surface cache lock is already held here, and then we acquire
|
||||
// mFramesMutex. For this method, this ordering is unavoidable, which means
|
||||
|
@ -126,7 +127,8 @@ AnimationSurfaceProvider::AddSizeOfExcludingThis(MallocSizeOf aMallocSizeOf,
|
|||
MutexAutoLock lock(mFramesMutex);
|
||||
|
||||
for (const RawAccessFrameRef& frame : mFrames) {
|
||||
frame->AddSizeOfExcludingThis(aMallocSizeOf, aHeapSizeOut, aNonHeapSizeOut);
|
||||
frame->AddSizeOfExcludingThis(aMallocSizeOf, aHeapSizeOut,
|
||||
aNonHeapSizeOut, aSharedHandlesOut);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче