/* 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";
let fluentBundles; if (webConsoleUI.isBrowserConsole) { const fluentL10n = new FluentL10n();
await fluentL10n.init(["devtools/client/toolbox.ftl"]);
fluentBundles = fluentL10n.getBundles();
}
returnnew Promise(resolve => {
store = configureStore(this.webConsoleUI, { // We may not have access to the toolbox (e.g. in the browser console).
telemetry: this.telemetry,
thunkArgs: {
webConsoleUI,
hud: this.hud,
toolbox: this.toolbox,
commands: this.hud.commands,
},
});
this.body = ReactDOM.render(
createElement(
Provider,
{ store },
createElement(
createProvider(this.hud.commands.targetCommand.storeId),
{ store: this.hud.commands.targetCommand.store },
maybeLocalizedElement
)
), this.parentNode
);
} else { // If there's no parentNode, we are in a test. So we can resolve immediately.
resolve();
}
});
}
destroy() { // This component can be instantiated from jest test, in which case we don't have // a parentNode reference. if (this.parentNode) {
ReactDOM.unmountComponentAtNode(this.parentNode);
}
}
/** * Query the reducer store for the current state of filtering * a given type of message * * @param {String} filter * Type of message to be filtered. * @return {Boolean} * True if this type of message should be displayed.
*/
getFilterState(filter) { return getAllFilters(this.getStore().getState())[filter];
}
dispatchMessagesClear() { // We might still have pending message additions and updates when the clear action is // triggered, so we need to flush them to make sure we don't have unexpected behavior // in the ConsoleOutput. *But* we want to keep any pending navigation request, // as we want to keep displaying them even if we received a clear request. function filter(l) { return l.filter(update => update.isNavigationRequest);
} this.queuedMessageAdds = filter(this.queuedMessageAdds); this.queuedMessageUpdates = filter(this.queuedMessageUpdates); this.queuedRequestUpdates = this.queuedRequestUpdates.filter(
update => update.data.isNavigationRequest
);
dispatchPrivateMessagesClear() { // We might still have pending private message additions when the private messages // clear action is triggered. We need to remove any private-window-issued packets from // the queue so they won't appear in the output.
// For (network) message updates, we need to check both messages queue and the state // since we can receive updates even if the message isn't rendered yet. const messages = [...getMutableMessagesById(store.getState()).values()]; this.queuedMessageUpdates = this.queuedMessageUpdates.filter(
({ actor }) => { const queuedNetworkMessage = this.queuedMessageAdds.find(
p => p.actor === actor
); if (queuedNetworkMessage && isPacketPrivate(queuedNetworkMessage)) { returnfalse;
}
const requestMessage = messages.find(
message => actor === message.actor
); if (requestMessage && requestMessage.private === true) { returnfalse;
}
returntrue;
}
);
// For (network) requests updates, we can check only the state, since there must be a // user interaction to get an update (i.e. the network message is displayed and thus // in the state). this.queuedRequestUpdates = this.queuedRequestUpdates.filter(({ id }) => { const requestMessage = getMessage(store.getState(), id); if (requestMessage && requestMessage.private === true) { returnfalse;
}
returntrue;
});
// Finally we clear the messages queue. This needs to be done here since we use it to // clean the other queues. this.queuedMessageAdds = this.queuedMessageAdds.filter(
p => !isPacketPrivate(p)
);
store.dispatch(actions.privateMessagesClear());
}
dispatchTargetMessagesRemove(targetFront) { // We might still have pending packets in the queues from the target that we need to remove // to prevent messages appearing in the output.
for (let i = this.queuedMessageUpdates.length - 1; i >= 0; i--) { const packet = this.queuedMessageUpdates[i]; if (packet.targetFront == targetFront) { this.queuedMessageUpdates.splice(i, 1);
}
}
for (let i = this.queuedRequestUpdates.length - 1; i >= 0; i--) { const packet = this.queuedRequestUpdates[i]; if (packet.data.targetFront == targetFront) { this.queuedRequestUpdates.splice(i, 1);
}
}
for (let i = this.queuedMessageAdds.length - 1; i >= 0; i--) { const packet = this.queuedMessageAdds[i]; // Keep in sync with the check done in the reducer for the TARGET_MESSAGES_REMOVE action. if (
packet.targetFront == targetFront &&
packet.type !== Constants.MESSAGE_TYPE.COMMAND &&
packet.type !== Constants.MESSAGE_TYPE.RESULT
) { this.queuedMessageAdds.splice(i, 1);
}
}
// For the browser console, we receive tab navigation // when the original top level window we attached to is closed, // but we don't want to reset console history and just switch to // the next available window. if (ui.persistLogs || this.webConsoleUI.isBrowserConsole) { // Add a type in order for this event packet to be identified by // utils/messages.js's `transformPacket`
packet.type = "will-navigate"; this.dispatchMessageAdd(packet);
} else { this.dispatchMessagesClear();
store.dispatch({
type: Constants.WILL_NAVIGATE,
});
}
}
batchedMessagesUpdates(messages) { if (messages.length) { this.queuedMessageUpdates.push(...messages); this.setTimeoutIfNeeded();
}
}
/** * Returns a Promise that resolves once any async dispatch is finally dispatched.
*/
waitAsyncDispatches() { if (!this.throttledDispatchPromise) { return Promise.resolve();
} // When closing the console during initialization, // setTimeoutIfNeeded may never resolve its promise // as window.setTimeout will be disabled on document destruction. const onUnload = new Promise(r =>
window.addEventListener("unload", r, { once: true })
); return Promise.race([this.throttledDispatchPromise, onUnload]);
}
setTimeoutIfNeeded() { if (this.throttledDispatchPromise) { returnthis.throttledDispatchPromise;
} this.throttledDispatchPromise = new Promise(done => {
setTimeout(async () => { this.throttledDispatchPromise = null;
if (!store) { // The store is not initialized yet, we can call setTimeoutIfNeeded so the // messages will be handled in the next timeout when the store is ready. this.setTimeoutIfNeeded();
done(); return;
}
// This telemetry event is only useful when we have a toolbox so only // send it when we have one. if (this.toolbox) { this.telemetry.addEventProperty( this.toolbox, "enter", "webconsole", null, "message_count",
length
);
}
// Fire an event indicating that all data fetched from // the backend has been received. This is based on // 'FirefoxDataProvider.isQueuePayloadReady', see more // comments in that method. // (netmonitor/src/connector/firefox-data-provider). // This event might be utilized in tests to find the right // time when to finish.
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.