merge mozilla-inbound to mozilla-central a=merge

This commit is contained in:
Carsten "Tomcat" Book 2017-02-24 11:46:38 +01:00
Родитель 5e93eb6ceb 36611ba3ae
Коммит 7256146318
269 изменённых файлов: 3743 добавлений и 2922 удалений

Просмотреть файл

@ -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,
userContextId: aUserContextId,
sameProcessAsFrameLoader: aSameProcessAsFrameLoader,
opener: aOpener,
isPrerendered: aIsPrerendered,
};
let { usingPreloadedContent } = this._linkBrowserToTab(t, aURI, browserParams);
let b = t.linkedBrowser;
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 });
}
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) {
var cMap = new CMap(true);
var lexer = new Lexer(new StringStream(request.responseText));
parseCMap(cMap, lexer, builtInCMapParams, null).then(function (parsedCMap) {
resolve(parsedCMap);
});
} else {
reject(new Error('Unable to get cMap at: ' + url));
}
}
};
request.open('GET', url, true);
request.send(null);
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);
if (compressionType === CMapCompressionType.BINARY) {
return new BinaryCMapReader().process(cMapData, cMap, function (useCMap) {
return extendCMap(cMap, fetchBuiltInCMap, useCMap);
});
}
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];
try {
this.setTitle(decodeURIComponent(pdfjsLib.getFilenameFromUrl(url)) || url);
} catch (e) {
this.setTitle(url);
var title = getPDFFileNameFromURL(url, '');
if (!title) {
try {
title = decodeURIComponent(pdfjsLib.getFilenameFromUrl(url)) || url;
} catch (e) {
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');
this._bindLink(button, item.content, filename);
button.textContent = pdfjsLib.removeNullCharacters(filename);
button.textContent = filename;
if (/\.pdf$/i.test(filename)) {
this._bindPdfLink(button, item.content, filename);
} else {
this._bindLink(button, item.content, 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
* @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
*
* @param {String|NodeFront} selectorOrNodeFront
* The selector for the node to be set, or the nodeFront.
* @param {InspectorPanel} inspector
* 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");
inspector.sidebar.select(id);
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),
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();
xpc::NukeAllWrappersForCompartment(cx, cpt,
win->IsInnerWindow() ? js::DontNukeWindowReferences
: js::NukeWindowReferences);
} 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

Двоичный файл не отображается.

Просмотреть файл

@ -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,17 +275,21 @@ 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)) {
ok(name in self === interfaceMap[name],
name + " should " + (interfaceMap[name] ? "" : " NOT") + " be defined on the global scope");
if (!interfaceMap[name]) {
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,

Просмотреть файл

@ -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,17 +289,21 @@ 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)) {
ok(name in self === interfaceMap[name],
name + " should " + (interfaceMap[name] ? "" : " NOT") + " be defined on the global scope");
if (!interfaceMap[name]) {
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,

Просмотреть файл

@ -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);
}
}

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше