зеркало из https://github.com/mozilla/gecko-dev.git
Merge autoland to mozilla-central. a=merge
This commit is contained in:
Коммит
f5a9cfc509
4
.flake8
4
.flake8
|
@ -25,7 +25,6 @@ exclude =
|
|||
python/devtools/migrate-l10n/migrate/main.py,
|
||||
python/l10n/fluent_migrations,
|
||||
python/mozbuild/dumbmake,
|
||||
python/mozbuild/mozbuild,
|
||||
servo/components/style,
|
||||
testing/jsshell/benchmark.py,
|
||||
testing/marionette/mach_commands.py,
|
||||
|
@ -69,6 +68,7 @@ exclude =
|
|||
memory/moz.configure,
|
||||
mobile/android/*.configure,
|
||||
node_modules,
|
||||
python/mozbuild/mozbuild/test/configure/data,
|
||||
security/nss/,
|
||||
testing/marionette/harness/marionette_harness/runner/mixins,
|
||||
testing/marionette/harness/marionette_harness/tests,
|
||||
|
@ -92,6 +92,8 @@ ignore =
|
|||
|
||||
per-file-ignores =
|
||||
ipc/ipdl/*: F403, F405
|
||||
# cpp_eclipse has a lot of multi-line embedded XML which exceeds line length
|
||||
python/mozbuild/mozbuild/backend/cpp_eclipse.py: E501
|
||||
testing/firefox-ui/**/__init__.py: F401
|
||||
testing/marionette/**/__init__.py: F401
|
||||
testing/mozharness/configs/*: E124, E127, E128, E131, E231, E261, E265, E266, E501, W391
|
||||
|
|
|
@ -503,8 +503,13 @@ pref("browser.tabs.delayHidingAudioPlayingIconMS", 3000);
|
|||
pref("browser.tabs.remote.separatePrivilegedContentProcess", true);
|
||||
#endif
|
||||
|
||||
// Turn on HTTP response process selection.
|
||||
#ifdef NIGHTLY_BUILD
|
||||
pref("browser.tabs.remote.useHTTPResponseProcessSelection", true);
|
||||
#else
|
||||
// Disabled outside of nightly due to bug 1554217
|
||||
pref("browser.tabs.remote.useHTTPResponseProcessSelection", false);
|
||||
#endif
|
||||
|
||||
|
||||
// Unload tabs when available memory is running low
|
||||
pref("browser.tabs.unloadOnLowMemory", true);
|
||||
|
|
|
@ -1440,6 +1440,10 @@ var gBrowserInit = {
|
|||
}
|
||||
}
|
||||
|
||||
if (Services.prefs.getBoolPref("toolkit.legacyUserProfileCustomizations.windowIcon", false)) {
|
||||
document.documentElement.setAttribute("icon", "main-window");
|
||||
}
|
||||
|
||||
// Call this after we set attributes that might change toolbars' computed
|
||||
// text color.
|
||||
ToolbarIconColor.init();
|
||||
|
@ -8061,7 +8065,7 @@ var RestoreLastSessionObserver = {
|
|||
!PrivateBrowsingUtils.isWindowPrivate(window)) {
|
||||
Services.obs.addObserver(this, "sessionstore-last-session-cleared", true);
|
||||
goSetCommandEnabled("Browser:RestoreLastSession", true);
|
||||
} else if (SessionStartup.isAutomaticRestoreEnabled()) {
|
||||
} else if (SessionStore.willAutoRestore) {
|
||||
document.getElementById("Browser:RestoreLastSession").setAttribute("hidden", true);
|
||||
}
|
||||
},
|
||||
|
|
|
@ -416,6 +416,7 @@ XPCOMUtils.defineLazyGetter(this, "WeaveService", () =>
|
|||
// lazy module getters
|
||||
|
||||
XPCOMUtils.defineLazyModuleGetters(this, {
|
||||
AboutCertViewerHandler: "resource://gre/modules/AboutCertViewerHandler.jsm",
|
||||
AboutNetErrorHandler: "resource:///modules/aboutpages/AboutNetErrorHandler.jsm",
|
||||
AboutPrivateBrowsingHandler: "resource:///modules/aboutpages/AboutPrivateBrowsingHandler.jsm",
|
||||
AboutProtectionsHandler: "resource:///modules/aboutpages/AboutProtectionsHandler.jsm",
|
||||
|
@ -1386,6 +1387,8 @@ BrowserGlue.prototype = {
|
|||
|
||||
NewTabUtils.init();
|
||||
|
||||
AboutCertViewerHandler.init();
|
||||
|
||||
AboutNetErrorHandler.init();
|
||||
|
||||
AboutPrivateBrowsingHandler.init();
|
||||
|
@ -1538,6 +1541,7 @@ BrowserGlue.prototype = {
|
|||
|
||||
PageThumbs.uninit();
|
||||
NewTabUtils.uninit();
|
||||
AboutCertViewerHandler.uninit();
|
||||
AboutNetErrorHandler.uninit();
|
||||
AboutPrivateBrowsingHandler.uninit();
|
||||
AboutProtectionsHandler.uninit();
|
||||
|
|
|
@ -35,7 +35,6 @@ XPCOMUtils.defineLazyServiceGetter(this, "Telemetry",
|
|||
|
||||
XPCOMUtils.defineLazyModuleGetters(this, {
|
||||
RunState: "resource:///modules/sessionstore/RunState.jsm",
|
||||
SessionStartup: "resource:///modules/sessionstore/SessionStartup.jsm",
|
||||
SessionStore: "resource:///modules/sessionstore/SessionStore.jsm",
|
||||
SessionWorker: "resource:///modules/sessionstore/SessionWorker.jsm",
|
||||
});
|
||||
|
@ -382,8 +381,7 @@ var SessionFileInternal = {
|
|||
RunState.setClosed();
|
||||
}
|
||||
|
||||
let performShutdownCleanup = isFinalWrite &&
|
||||
!SessionStartup.isAutomaticRestoreEnabled();
|
||||
let performShutdownCleanup = isFinalWrite && !SessionStore.willAutoRestore;
|
||||
|
||||
this._attempts++;
|
||||
let options = {isFinalWrite, performShutdownCleanup};
|
||||
|
|
|
@ -155,6 +155,9 @@ const RESTORE_TAB_CONTENT_REASON = {
|
|||
NAVIGATE_AND_RESTORE: 1,
|
||||
};
|
||||
|
||||
// 'browser.startup.page' preference value to resume the previous session.
|
||||
const BROWSER_STARTUP_RESUME_SESSION = 3;
|
||||
|
||||
ChromeUtils.import("resource://gre/modules/PrivateBrowsingUtils.jsm", this);
|
||||
ChromeUtils.import("resource://gre/modules/Services.jsm", this);
|
||||
ChromeUtils.import("resource://gre/modules/TelemetryTimestamps.jsm", this);
|
||||
|
@ -233,6 +236,10 @@ var SessionStore = {
|
|||
return SessionStoreInternal.lastClosedObjectType;
|
||||
},
|
||||
|
||||
get willAutoRestore() {
|
||||
return SessionStoreInternal.willAutoRestore;
|
||||
},
|
||||
|
||||
init: function ss_init() {
|
||||
SessionStoreInternal.init();
|
||||
},
|
||||
|
@ -619,6 +626,16 @@ var SessionStoreInternal = {
|
|||
return "tab";
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns a boolean that determines whether the session will be automatically
|
||||
* restored upon the _next_ startup or a restart.
|
||||
*/
|
||||
get willAutoRestore() {
|
||||
return !PrivateBrowsingUtils.permanentPrivateBrowsing &&
|
||||
(Services.prefs.getBoolPref("browser.sessionstore.resume_session_once") ||
|
||||
Services.prefs.getIntPref("browser.startup.page") == BROWSER_STARTUP_RESUME_SESSION);
|
||||
},
|
||||
|
||||
/**
|
||||
* Initialize the sessionstore service.
|
||||
*/
|
||||
|
|
|
@ -306,6 +306,7 @@ early_options = early_options()
|
|||
# This gives access to the sandbox. Don't copy this blindly.
|
||||
@imports('__sandbox__')
|
||||
@imports('os')
|
||||
@imports('six')
|
||||
def mozconfig_options(mozconfig, automation, help):
|
||||
if mozconfig['path']:
|
||||
if 'MOZ_AUTOMATION_MOZCONFIG' in mozconfig['env']['added']:
|
||||
|
@ -331,15 +332,15 @@ def mozconfig_options(mozconfig, automation, help):
|
|||
log.info(' %s' % arg)
|
||||
helper.add(arg, origin='mozconfig', args=helper._args)
|
||||
|
||||
for key, value in mozconfig['env']['added'].iteritems():
|
||||
for key, value in six.iteritems(mozconfig['env']['added']):
|
||||
add(key, value)
|
||||
os.environ[key] = value
|
||||
for key, (_, value) in mozconfig['env']['modified'].iteritems():
|
||||
for key, (_, value) in six.iteritems(mozconfig['env']['modified']):
|
||||
add(key, value)
|
||||
os.environ[key] = value
|
||||
for key, value in mozconfig['vars']['added'].iteritems():
|
||||
for key, value in six.iteritems(mozconfig['vars']['added']):
|
||||
add(key, value)
|
||||
for key, (_, value) in mozconfig['vars']['modified'].iteritems():
|
||||
for key, (_, value) in six.iteritems(mozconfig['vars']['modified']):
|
||||
add(key, value)
|
||||
|
||||
|
||||
|
|
|
@ -63,18 +63,13 @@ if __name__ == '__main__':
|
|||
for path in prefpaths:
|
||||
prefs.update(Preferences.read_prefs(path))
|
||||
|
||||
interpolation = {"server": "%s:%d" % httpd.httpd.server_address}
|
||||
interpolation = {"server": "%s:%d" % httpd.httpd.server_address,
|
||||
"OOP": "false"}
|
||||
for k, v in prefs.items():
|
||||
if isinstance(v, string_types):
|
||||
v = v.format(**interpolation)
|
||||
prefs[k] = Preferences.cast(v)
|
||||
|
||||
# Enforce e10s. This isn't in one of the user.js files because those
|
||||
# are shared with android, which doesn't want this on. We can't
|
||||
# interpolate because the formatting code only works for strings,
|
||||
# and this is a bool pref.
|
||||
prefs["browser.tabs.remote.autostart"] = True
|
||||
|
||||
profile = FirefoxProfile(profile=profilePath,
|
||||
preferences=prefs,
|
||||
addons=[os.path.join(
|
||||
|
@ -85,9 +80,10 @@ if __name__ == '__main__':
|
|||
env = os.environ.copy()
|
||||
env["MOZ_CRASHREPORTER_NO_REPORT"] = "1"
|
||||
env["XPCOM_DEBUG_BREAK"] = "warn"
|
||||
# We disable sandboxing to make writing profiling data actually work
|
||||
# Bug 1553850 considers fixing this.
|
||||
env["MOZ_DISABLE_CONTENT_SANDBOX"] = "1"
|
||||
# TODO should use e10s and gather data from all processes (bug 1196094).
|
||||
# Note that unittest-required/user.js sets the autostart pref, but it
|
||||
# is ignored by the code in nsAppRunner.
|
||||
env["MOZ_FORCE_DISABLE_E10S"] = "1"
|
||||
|
||||
# For VC12+, make sure we can find the right bitness of pgort1x0.dll
|
||||
if not substs.get('HAVE_64BIT_BUILD'):
|
||||
|
|
|
@ -63,13 +63,6 @@ nsChromeProtocolHandler::GetProtocolFlags(uint32_t* result) {
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsChromeProtocolHandler::NewURI(const nsACString& aSpec, const char* aCharset,
|
||||
nsIURI* aBaseURI, nsIURI** result) {
|
||||
return nsChromeProtocolHandler::CreateNewURI(aSpec, aCharset, aBaseURI,
|
||||
result);
|
||||
}
|
||||
|
||||
/* static */ nsresult nsChromeProtocolHandler::CreateNewURI(
|
||||
const nsACString& aSpec, const char* aCharset, nsIURI* aBaseURI,
|
||||
nsIURI** result) {
|
||||
|
|
|
@ -20,16 +20,6 @@ ProtocolHandler.prototype =
|
|||
{
|
||||
defaultPort: -1,
|
||||
allowPort: () => false,
|
||||
newURI(aSpec, aCharset, aBaseURI) {
|
||||
let mutator = Cc["@mozilla.org/network/standard-url-mutator;1"]
|
||||
.createInstance(Ci.nsIURIMutator);
|
||||
if (aBaseURI) {
|
||||
mutator.setSpec(aBaseURI.resolve(aSpec));
|
||||
} else {
|
||||
mutator.setSpec(aSpec);
|
||||
}
|
||||
return mutator.finalize();
|
||||
},
|
||||
newChannel() { throw Cr.NS_ERROR_NOT_IMPLEMENTED; },
|
||||
QueryInterface: ChromeUtils.generateQI([
|
||||
Ci.nsIProtocolHandler,
|
||||
|
|
|
@ -6,7 +6,10 @@
|
|||
# longer present in a complete update. The current working directory is used for
|
||||
# the location to enumerate and to create the precomplete file.
|
||||
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import os
|
||||
import io
|
||||
|
||||
|
||||
def get_build_entries(root_path):
|
||||
|
@ -54,13 +57,13 @@ def generate_precomplete(root_path):
|
|||
precomplete_file_path = os.path.join(root_path, rel_path_precomplete)
|
||||
# Open the file so it exists before building the list of files and open it
|
||||
# in binary mode to prevent OS specific line endings.
|
||||
precomplete_file = open(precomplete_file_path, "wb")
|
||||
precomplete_file = io.open(precomplete_file_path, mode="wt", newline='\n')
|
||||
rel_file_path_list, rel_dir_path_list = get_build_entries(root_path)
|
||||
for rel_file_path in rel_file_path_list:
|
||||
precomplete_file.writelines("remove \""+rel_file_path+"\"\n")
|
||||
precomplete_file.write("remove \""+rel_file_path+"\"\n")
|
||||
|
||||
for rel_dir_path in rel_dir_path_list:
|
||||
precomplete_file.writelines("rmdir \""+rel_dir_path+"\"\n")
|
||||
precomplete_file.write("rmdir \""+rel_dir_path+"\"\n")
|
||||
|
||||
precomplete_file.close()
|
||||
|
||||
|
|
|
@ -14,6 +14,7 @@ import textwrap
|
|||
|
||||
base_dir = os.path.abspath(os.path.dirname(__file__))
|
||||
sys.path.insert(0, os.path.join(base_dir, 'python', 'mozbuild'))
|
||||
sys.path.insert(0, os.path.join(base_dir, 'third_party', 'python', 'six'))
|
||||
from mozbuild.configure import (
|
||||
ConfigureSandbox,
|
||||
TRACE,
|
||||
|
|
|
@ -53,6 +53,7 @@ type State = {
|
|||
selectedResultIndex: number,
|
||||
count: number,
|
||||
index: number,
|
||||
inputFocused: boolean,
|
||||
};
|
||||
|
||||
type Props = {
|
||||
|
@ -82,6 +83,7 @@ class SearchBar extends Component<Props, State> {
|
|||
selectedResultIndex: 0,
|
||||
count: 0,
|
||||
index: -1,
|
||||
inputFocused: false,
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -146,7 +148,7 @@ class SearchBar extends Component<Props, State> {
|
|||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
}
|
||||
this.setState({ query: "" });
|
||||
this.setState({ query: "", inputFocused: false });
|
||||
};
|
||||
|
||||
toggleSearch = (e: SyntheticKeyboardEvent<HTMLElement>) => {
|
||||
|
@ -162,10 +164,10 @@ class SearchBar extends Component<Props, State> {
|
|||
const query = editor.codeMirror.getSelection() || this.state.query;
|
||||
|
||||
if (query !== "") {
|
||||
this.setState({ query });
|
||||
this.setState({ query, inputFocused: true });
|
||||
this.doSearch(query);
|
||||
} else {
|
||||
this.setState({ query: "" });
|
||||
this.setState({ query: "", inputFocused: true });
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -198,6 +200,14 @@ class SearchBar extends Component<Props, State> {
|
|||
return this.doSearch(e.target.value);
|
||||
};
|
||||
|
||||
onFocus = (e: SyntheticFocusEvent<HTMLElement>) => {
|
||||
this.setState({ inputFocused: true });
|
||||
};
|
||||
|
||||
onBlur = (e: SyntheticFocusEvent<HTMLElement>) => {
|
||||
this.setState({ inputFocused: false });
|
||||
};
|
||||
|
||||
onKeyDown = (e: any) => {
|
||||
if (e.key !== "Enter" && e.key !== "F3") {
|
||||
return;
|
||||
|
@ -320,11 +330,14 @@ class SearchBar extends Component<Props, State> {
|
|||
summaryMsg={this.buildSummaryMsg()}
|
||||
isLoading={false}
|
||||
onChange={this.onChange}
|
||||
onFocus={this.onFocus}
|
||||
onBlur={this.onBlur}
|
||||
showErrorEmoji={this.shouldShowErrorEmoji()}
|
||||
onKeyDown={this.onKeyDown}
|
||||
onHistoryScroll={this.onHistoryScroll}
|
||||
handleNext={e => this.traverseResults(e, false)}
|
||||
handlePrev={e => this.traverseResults(e, true)}
|
||||
shouldFocus={this.state.inputFocused}
|
||||
showClose={false}
|
||||
/>
|
||||
<div className="search-bottom-bar">
|
||||
|
|
|
@ -10,12 +10,15 @@ exports[`SearchBar should render 1`] = `
|
|||
handlePrev={[Function]}
|
||||
hasPrefix={false}
|
||||
isLoading={false}
|
||||
onBlur={[Function]}
|
||||
onChange={[Function]}
|
||||
onFocus={[Function]}
|
||||
onHistoryScroll={[Function]}
|
||||
onKeyDown={[Function]}
|
||||
placeholder="Find in file…"
|
||||
query=""
|
||||
selectedItemId=""
|
||||
shouldFocus={false}
|
||||
showClose={false}
|
||||
showErrorEmoji={false}
|
||||
size=""
|
||||
|
@ -80,12 +83,15 @@ exports[`showErrorEmoji false if no query + no results 1`] = `
|
|||
handlePrev={[Function]}
|
||||
hasPrefix={false}
|
||||
isLoading={false}
|
||||
onBlur={[Function]}
|
||||
onChange={[Function]}
|
||||
onFocus={[Function]}
|
||||
onHistoryScroll={[Function]}
|
||||
onKeyDown={[Function]}
|
||||
placeholder="Find in file…"
|
||||
query=""
|
||||
selectedItemId=""
|
||||
shouldFocus={false}
|
||||
showClose={false}
|
||||
showErrorEmoji={false}
|
||||
size=""
|
||||
|
@ -148,12 +154,15 @@ exports[`showErrorEmoji false if query + results 1`] = `
|
|||
handlePrev={[Function]}
|
||||
hasPrefix={false}
|
||||
isLoading={false}
|
||||
onBlur={[Function]}
|
||||
onChange={[Function]}
|
||||
onFocus={[Function]}
|
||||
onHistoryScroll={[Function]}
|
||||
onKeyDown={[Function]}
|
||||
placeholder="Find in file…"
|
||||
query="test"
|
||||
selectedItemId=""
|
||||
shouldFocus={false}
|
||||
showClose={false}
|
||||
showErrorEmoji={false}
|
||||
size=""
|
||||
|
@ -216,12 +225,15 @@ exports[`showErrorEmoji true if query + no results 1`] = `
|
|||
handlePrev={[Function]}
|
||||
hasPrefix={false}
|
||||
isLoading={false}
|
||||
onBlur={[Function]}
|
||||
onChange={[Function]}
|
||||
onFocus={[Function]}
|
||||
onHistoryScroll={[Function]}
|
||||
onKeyDown={[Function]}
|
||||
placeholder="Find in file…"
|
||||
query="test"
|
||||
selectedItemId=""
|
||||
shouldFocus={false}
|
||||
showClose={false}
|
||||
showErrorEmoji={true}
|
||||
size=""
|
||||
|
|
|
@ -56,6 +56,7 @@ type Item = Result | Match;
|
|||
|
||||
type State = {
|
||||
inputValue: string,
|
||||
inputFocused: boolean,
|
||||
focusedItem: ?Item,
|
||||
};
|
||||
|
||||
|
@ -89,6 +90,7 @@ export class ProjectSearch extends Component<Props, State> {
|
|||
super(props);
|
||||
this.state = {
|
||||
inputValue: this.props.query || "",
|
||||
inputFocused: false,
|
||||
focusedItem: null,
|
||||
};
|
||||
}
|
||||
|
@ -177,7 +179,11 @@ export class ProjectSearch extends Component<Props, State> {
|
|||
};
|
||||
|
||||
onEnterPress = () => {
|
||||
if (!this.isProjectSearchEnabled() || !this.state.focusedItem) {
|
||||
if (
|
||||
!this.isProjectSearchEnabled() ||
|
||||
!this.state.focusedItem ||
|
||||
this.state.inputFocused
|
||||
) {
|
||||
return;
|
||||
}
|
||||
if (this.state.focusedItem.type === "MATCH") {
|
||||
|
@ -295,6 +301,8 @@ export class ProjectSearch extends Component<Props, State> {
|
|||
summaryMsg={this.renderSummary()}
|
||||
isLoading={status === statusType.fetching}
|
||||
onChange={this.inputOnChange}
|
||||
onFocus={() => this.setState({ inputFocused: true })}
|
||||
onBlur={() => this.setState({ inputFocused: false })}
|
||||
onKeyDown={this.onKeyDown}
|
||||
onHistoryScroll={this.onHistoryScroll}
|
||||
handleClose={
|
||||
|
|
|
@ -22,6 +22,7 @@ import {
|
|||
isSymbolsLoading,
|
||||
getContext,
|
||||
} from "../selectors";
|
||||
import { memoizeLast } from "../utils/memoizeLast";
|
||||
import { scrollList } from "../utils/result-list";
|
||||
import {
|
||||
formatSymbols,
|
||||
|
@ -131,11 +132,15 @@ export class QuickOpenModal extends Component<Props, State> {
|
|||
return query.split(":")[0];
|
||||
};
|
||||
|
||||
formatSources = memoizeLast((displayedSources, tabs) => {
|
||||
const tabUrls = new Set(tabs.map((tab: Tab) => tab.url));
|
||||
return formatSources(displayedSources, tabUrls);
|
||||
});
|
||||
|
||||
searchSources = (query: string) => {
|
||||
const { displayedSources, tabs } = this.props;
|
||||
const tabUrls = new Set(tabs.map((tab: Tab) => tab.url));
|
||||
const sources = formatSources(displayedSources, tabUrls);
|
||||
|
||||
const sources = this.formatSources(displayedSources, tabs);
|
||||
const results =
|
||||
query == "" ? sources : filter(sources, this.dropGoto(query));
|
||||
return this.setResults(results);
|
||||
|
|
|
@ -35,13 +35,16 @@ type Props = {
|
|||
handleNext?: (e: SyntheticMouseEvent<HTMLButtonElement>) => void,
|
||||
handlePrev?: (e: SyntheticMouseEvent<HTMLButtonElement>) => void,
|
||||
hasPrefix?: boolean,
|
||||
onBlur?: (e: SyntheticFocusEvent<HTMLInputElement>) => void,
|
||||
onChange: (e: SyntheticInputEvent<HTMLInputElement>) => void,
|
||||
onFocus?: (e: SyntheticFocusEvent<HTMLInputElement>) => void,
|
||||
onKeyDown: (e: SyntheticKeyboardEvent<HTMLInputElement>) => void,
|
||||
onKeyUp?: (e: SyntheticKeyboardEvent<HTMLInputElement>) => void,
|
||||
onHistoryScroll?: (historyValue: string) => void,
|
||||
placeholder: string,
|
||||
query: string,
|
||||
selectedItemId?: string,
|
||||
shouldFocus?: boolean,
|
||||
showErrorEmoji: boolean,
|
||||
size: string,
|
||||
summaryMsg: string,
|
||||
|
@ -77,6 +80,12 @@ class SearchInput extends Component<Props, State> {
|
|||
this.setFocus();
|
||||
}
|
||||
|
||||
componentDidUpdate(prevProps: Props) {
|
||||
if (this.props.shouldFocus && !prevProps.shouldFocus) {
|
||||
this.setFocus();
|
||||
}
|
||||
}
|
||||
|
||||
setFocus() {
|
||||
if (this.$input) {
|
||||
const input = this.$input;
|
||||
|
@ -115,6 +124,22 @@ class SearchInput extends Component<Props, State> {
|
|||
];
|
||||
}
|
||||
|
||||
onFocus = (e: SyntheticFocusEvent<HTMLInputElement>) => {
|
||||
const { onFocus } = this.props;
|
||||
|
||||
if (onFocus) {
|
||||
onFocus(e);
|
||||
}
|
||||
};
|
||||
|
||||
onBlur = (e: SyntheticFocusEvent<HTMLInputElement>) => {
|
||||
const { onBlur } = this.props;
|
||||
|
||||
if (onBlur) {
|
||||
onBlur(e);
|
||||
}
|
||||
};
|
||||
|
||||
onKeyDown = (e: any) => {
|
||||
const { onHistoryScroll, onKeyDown } = this.props;
|
||||
if (!onHistoryScroll) {
|
||||
|
@ -209,6 +234,8 @@ class SearchInput extends Component<Props, State> {
|
|||
onChange,
|
||||
onKeyDown: e => this.onKeyDown(e),
|
||||
onKeyUp,
|
||||
onFocus: e => this.onFocus(e),
|
||||
onBlur: e => this.onBlur(e),
|
||||
"aria-autocomplete": "list",
|
||||
"aria-controls": "result-list",
|
||||
"aria-activedescendant":
|
||||
|
|
|
@ -19,7 +19,9 @@ exports[`SearchInput renders 1`] = `
|
|||
aria-autocomplete="list"
|
||||
aria-controls="result-list"
|
||||
className=""
|
||||
onBlur={[Function]}
|
||||
onChange={[Function]}
|
||||
onFocus={[Function]}
|
||||
onKeyDown={[Function]}
|
||||
placeholder="A placeholder"
|
||||
spellCheck={false}
|
||||
|
@ -56,7 +58,9 @@ exports[`SearchInput shows nav buttons 1`] = `
|
|||
aria-autocomplete="list"
|
||||
aria-controls="result-list"
|
||||
className=""
|
||||
onBlur={[Function]}
|
||||
onChange={[Function]}
|
||||
onFocus={[Function]}
|
||||
onKeyDown={[Function]}
|
||||
placeholder="A placeholder"
|
||||
spellCheck={false}
|
||||
|
@ -119,7 +123,9 @@ exports[`SearchInput shows svg error emoji 1`] = `
|
|||
aria-autocomplete="list"
|
||||
aria-controls="result-list"
|
||||
className="empty"
|
||||
onBlur={[Function]}
|
||||
onChange={[Function]}
|
||||
onFocus={[Function]}
|
||||
onKeyDown={[Function]}
|
||||
placeholder="A placeholder"
|
||||
spellCheck={false}
|
||||
|
@ -182,7 +188,9 @@ exports[`SearchInput shows svg magnifying glass 1`] = `
|
|||
aria-autocomplete="list"
|
||||
aria-controls="result-list"
|
||||
className=""
|
||||
onBlur={[Function]}
|
||||
onChange={[Function]}
|
||||
onFocus={[Function]}
|
||||
onKeyDown={[Function]}
|
||||
placeholder="A placeholder"
|
||||
spellCheck={false}
|
||||
|
|
|
@ -16,7 +16,9 @@ exports[`ProjectSearch found no search results 1`] = `
|
|||
handleClose={[MockFunction]}
|
||||
hasPrefix={false}
|
||||
isLoading={false}
|
||||
onBlur={[Function]}
|
||||
onChange={[Function]}
|
||||
onFocus={[Function]}
|
||||
onHistoryScroll={[Function]}
|
||||
onKeyDown={[Function]}
|
||||
placeholder="Find in files…"
|
||||
|
@ -117,7 +119,9 @@ exports[`ProjectSearch found search results 1`] = `
|
|||
handleClose={[MockFunction]}
|
||||
hasPrefix={false}
|
||||
isLoading={false}
|
||||
onBlur={[Function]}
|
||||
onChange={[Function]}
|
||||
onFocus={[Function]}
|
||||
onHistoryScroll={[Function]}
|
||||
onKeyDown={[Function]}
|
||||
placeholder="Find in files…"
|
||||
|
@ -150,7 +154,9 @@ exports[`ProjectSearch found search results 1`] = `
|
|||
aria-autocomplete="list"
|
||||
aria-controls="result-list"
|
||||
className=""
|
||||
onBlur={[Function]}
|
||||
onChange={[Function]}
|
||||
onFocus={[Function]}
|
||||
onKeyDown={[Function]}
|
||||
placeholder="Find in files…"
|
||||
spellCheck={false}
|
||||
|
@ -744,7 +750,9 @@ exports[`ProjectSearch should display loading message while search is in progres
|
|||
handleClose={[MockFunction]}
|
||||
hasPrefix={false}
|
||||
isLoading={true}
|
||||
onBlur={[Function]}
|
||||
onChange={[Function]}
|
||||
onFocus={[Function]}
|
||||
onHistoryScroll={[Function]}
|
||||
onKeyDown={[Function]}
|
||||
placeholder="Find in files…"
|
||||
|
@ -781,7 +789,9 @@ exports[`ProjectSearch showErrorEmoji false if not done & no results 1`] = `
|
|||
handleClose={[MockFunction]}
|
||||
hasPrefix={false}
|
||||
isLoading={true}
|
||||
onBlur={[Function]}
|
||||
onChange={[Function]}
|
||||
onFocus={[Function]}
|
||||
onHistoryScroll={[Function]}
|
||||
onKeyDown={[Function]}
|
||||
placeholder="Find in files…"
|
||||
|
@ -818,7 +828,9 @@ exports[`ProjectSearch showErrorEmoji false if not done & results 1`] = `
|
|||
handleClose={[MockFunction]}
|
||||
hasPrefix={false}
|
||||
isLoading={true}
|
||||
onBlur={[Function]}
|
||||
onChange={[Function]}
|
||||
onFocus={[Function]}
|
||||
onHistoryScroll={[Function]}
|
||||
onKeyDown={[Function]}
|
||||
placeholder="Find in files…"
|
||||
|
@ -863,7 +875,9 @@ exports[`ProjectSearch turns off shortcuts on unmount 1`] = `
|
|||
handleClose={[MockFunction]}
|
||||
hasPrefix={false}
|
||||
isLoading={false}
|
||||
onBlur={[Function]}
|
||||
onChange={[Function]}
|
||||
onFocus={[Function]}
|
||||
onHistoryScroll={[Function]}
|
||||
onKeyDown={[Function]}
|
||||
placeholder="Find in files…"
|
||||
|
@ -895,7 +909,9 @@ exports[`ProjectSearch where <Enter> has not been pressed 1`] = `
|
|||
handleClose={[MockFunction]}
|
||||
hasPrefix={false}
|
||||
isLoading={false}
|
||||
onBlur={[Function]}
|
||||
onChange={[Function]}
|
||||
onFocus={[Function]}
|
||||
onHistoryScroll={[Function]}
|
||||
onKeyDown={[Function]}
|
||||
placeholder="Find in files…"
|
||||
|
|
|
@ -98,7 +98,9 @@ exports[`QuickOpenModal Basic render with mount & searchType = functions 1`] = `
|
|||
aria-autocomplete="list"
|
||||
aria-controls="result-list"
|
||||
className="empty"
|
||||
onBlur={[Function]}
|
||||
onChange={[Function]}
|
||||
onFocus={[Function]}
|
||||
onKeyDown={[Function]}
|
||||
placeholder="Go to file…"
|
||||
spellCheck={false}
|
||||
|
@ -229,7 +231,9 @@ exports[`QuickOpenModal Basic render with mount & searchType = variables 1`] = `
|
|||
aria-autocomplete="list"
|
||||
aria-controls="result-list"
|
||||
className="empty"
|
||||
onBlur={[Function]}
|
||||
onChange={[Function]}
|
||||
onFocus={[Function]}
|
||||
onKeyDown={[Function]}
|
||||
placeholder="Go to file…"
|
||||
spellCheck={false}
|
||||
|
@ -343,7 +347,9 @@ exports[`QuickOpenModal Basic render with mount 1`] = `
|
|||
aria-autocomplete="list"
|
||||
aria-controls="result-list"
|
||||
className=""
|
||||
onBlur={[Function]}
|
||||
onChange={[Function]}
|
||||
onFocus={[Function]}
|
||||
onKeyDown={[Function]}
|
||||
placeholder="Go to file…"
|
||||
spellCheck={false}
|
||||
|
@ -509,7 +515,9 @@ exports[`QuickOpenModal Simple goto search query = :abc & searchType = goto 1`]
|
|||
aria-autocomplete="list"
|
||||
aria-controls="result-list"
|
||||
className="empty"
|
||||
onBlur={[Function]}
|
||||
onChange={[Function]}
|
||||
onFocus={[Function]}
|
||||
onKeyDown={[Function]}
|
||||
placeholder="Go to file…"
|
||||
spellCheck={false}
|
||||
|
@ -628,7 +636,9 @@ exports[`QuickOpenModal showErrorEmoji false when count + query 1`] = `
|
|||
aria-autocomplete="list"
|
||||
aria-controls="result-list"
|
||||
className=""
|
||||
onBlur={[Function]}
|
||||
onChange={[Function]}
|
||||
onFocus={[Function]}
|
||||
onKeyDown={[Function]}
|
||||
placeholder="Go to file…"
|
||||
spellCheck={false}
|
||||
|
@ -790,7 +800,9 @@ exports[`QuickOpenModal showErrorEmoji false when goto numeric ':2222' 1`] = `
|
|||
aria-autocomplete="list"
|
||||
aria-controls="result-list"
|
||||
className=""
|
||||
onBlur={[Function]}
|
||||
onChange={[Function]}
|
||||
onFocus={[Function]}
|
||||
onKeyDown={[Function]}
|
||||
placeholder="Go to file…"
|
||||
spellCheck={false}
|
||||
|
@ -909,7 +921,9 @@ exports[`QuickOpenModal showErrorEmoji false when no query 1`] = `
|
|||
aria-autocomplete="list"
|
||||
aria-controls="result-list"
|
||||
className=""
|
||||
onBlur={[Function]}
|
||||
onChange={[Function]}
|
||||
onFocus={[Function]}
|
||||
onKeyDown={[Function]}
|
||||
placeholder="Go to file…"
|
||||
spellCheck={false}
|
||||
|
@ -1039,7 +1053,9 @@ exports[`QuickOpenModal showErrorEmoji true when goto not numeric ':22k22' 1`] =
|
|||
aria-autocomplete="list"
|
||||
aria-controls="result-list"
|
||||
className="empty"
|
||||
onBlur={[Function]}
|
||||
onChange={[Function]}
|
||||
onFocus={[Function]}
|
||||
onKeyDown={[Function]}
|
||||
placeholder="Go to file…"
|
||||
spellCheck={false}
|
||||
|
@ -1158,7 +1174,9 @@ exports[`QuickOpenModal showErrorEmoji true when no count + query 1`] = `
|
|||
aria-autocomplete="list"
|
||||
aria-controls="result-list"
|
||||
className="empty"
|
||||
onBlur={[Function]}
|
||||
onChange={[Function]}
|
||||
onFocus={[Function]}
|
||||
onKeyDown={[Function]}
|
||||
placeholder="Go to file…"
|
||||
spellCheck={false}
|
||||
|
@ -1335,7 +1353,9 @@ exports[`QuickOpenModal updateResults on enable 2`] = `
|
|||
aria-autocomplete="list"
|
||||
aria-controls="result-list"
|
||||
className=""
|
||||
onBlur={[Function]}
|
||||
onChange={[Function]}
|
||||
onFocus={[Function]}
|
||||
onKeyDown={[Function]}
|
||||
placeholder="Go to file…"
|
||||
spellCheck={false}
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
/* 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/>. */
|
||||
|
||||
export function memoizeLast(fn) {
|
||||
let lastArgs: any[];
|
||||
let lastResult: any;
|
||||
|
||||
const memoized = (...args) => {
|
||||
if (
|
||||
lastArgs &&
|
||||
args.length === lastArgs.length &&
|
||||
args.every((arg, i) => arg === lastArgs[i])
|
||||
) {
|
||||
return lastResult;
|
||||
}
|
||||
|
||||
lastArgs = args;
|
||||
lastResult = fn(...args);
|
||||
|
||||
return lastResult;
|
||||
};
|
||||
|
||||
return memoized;
|
||||
}
|
||||
|
||||
export default memoizeLast;
|
|
@ -33,6 +33,7 @@ CompiledModules(
|
|||
'log.js',
|
||||
'makeRecord.js',
|
||||
'memoize.js',
|
||||
'memoizeLast.js',
|
||||
'memoizableAction.js',
|
||||
'path.js',
|
||||
'prefs.js',
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
/* 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/>. */
|
||||
|
||||
// @flow
|
||||
|
||||
import { memoizeLast } from "../memoizeLast";
|
||||
|
||||
const a = { number: 3 };
|
||||
const b = { number: 4 };
|
||||
|
||||
function add(...numberObjects) {
|
||||
return numberObjects.reduce((prev, cur) => prev + cur.number, 0);
|
||||
}
|
||||
|
||||
describe("memozie", () => {
|
||||
it("should re-calculate when a value changes", () => {
|
||||
const mAdd = memoizeLast(add);
|
||||
mAdd(a);
|
||||
expect(mAdd(a)).toEqual(3);
|
||||
mAdd(b);
|
||||
expect(mAdd(b)).toEqual(4);
|
||||
});
|
||||
|
||||
it("should only run once", () => {
|
||||
const mockAdd = jest.fn(add);
|
||||
const mAdd = memoizeLast(mockAdd);
|
||||
mAdd(a);
|
||||
mAdd(a);
|
||||
|
||||
expect(mockAdd.mock.calls[0]).toEqual([{ number: 3 }]);
|
||||
});
|
||||
});
|
|
@ -64,4 +64,10 @@ add_task(async function() {
|
|||
// selecting another source keeps search open
|
||||
await selectSource(dbg, "simple2");
|
||||
ok(findElement(dbg, "searchField"), "Search field is still visible");
|
||||
|
||||
// search is always focused regardless of when or how it was opened
|
||||
pressKey(dbg, "fileSearch");
|
||||
await clickElement(dbg, "codeMirror");
|
||||
pressKey(dbg, "fileSearch");
|
||||
is(dbg.win.document.activeElement.tagName, "INPUT", "Search field focused");
|
||||
});
|
||||
|
|
|
@ -240,11 +240,15 @@ networkMenu.sizeCached=cached
|
|||
# by a service worker.
|
||||
networkMenu.sizeServiceWorker=service worker
|
||||
|
||||
# LOCALIZATION NOTE (networkMenu.sizeServiceWorker): This is the label displayed
|
||||
# LOCALIZATION NOTE (networkMenu.blockedBy): This is the label displayed
|
||||
# in the network menu specifying the request was blocked by something.
|
||||
# %S is replaced by the blocked reason, which could be "DevTools", "CORS", etc.
|
||||
networkMenu.blockedBy=blocked by %S
|
||||
|
||||
# LOCALIZATION NOTE (networkMenu.blocked): This is a generic message for a
|
||||
# URL that has been blocked for an unknown reason
|
||||
networkMenu.blocked=blocked
|
||||
|
||||
# LOCALIZATION NOTE (networkMenu.totalMS2): This is the label displayed
|
||||
# in the network menu specifying the time for a request to finish (in milliseconds).
|
||||
networkMenu.totalMS2=%S ms
|
||||
|
|
|
@ -10,6 +10,7 @@ const PropTypes = require("devtools/client/shared/vendor/react-prop-types");
|
|||
const { getFormattedSize } = require("../utils/format-utils");
|
||||
const { L10N } = require("../utils/l10n");
|
||||
const { propertiesEqual } = require("../utils/request-utils");
|
||||
const { BLOCKED_REASON_MESSAGES } = require("../constants");
|
||||
|
||||
const SIZE_CACHED = L10N.getStr("networkMenu.sizeCached");
|
||||
const SIZE_SERVICE_WORKER = L10N.getStr("networkMenu.sizeServiceWorker");
|
||||
|
@ -45,7 +46,7 @@ class RequestListColumnTransferredSize extends Component {
|
|||
let text;
|
||||
|
||||
if (blockedReason) {
|
||||
text = L10N.getFormatStr("networkMenu.blockedBy", blockedReason);
|
||||
text = BLOCKED_REASON_MESSAGES[blockedReason] || L10N.getStr("networkMenu.blocked");
|
||||
} else if (fromCache || status === "304") {
|
||||
text = SIZE_CACHED;
|
||||
} else if (fromServiceWorker) {
|
||||
|
|
|
@ -400,6 +400,41 @@ const SUPPORTED_HTTP_CODES = [
|
|||
"511",
|
||||
];
|
||||
|
||||
// Keys are the codes provided by server, values are localization messages
|
||||
// prefixed by "netmonitor.blocked."
|
||||
const BLOCKED_REASON_MESSAGES = {
|
||||
devtools: "Blocked by DevTools",
|
||||
1001: "CORS disabled",
|
||||
1002: "CORS Failed",
|
||||
1003: "CORS Not HTTP",
|
||||
1004: "CORS Multiple Origin Not Allowed",
|
||||
1005: "CORS Missing Allow Origin",
|
||||
1006: "CORS No Allow Credentials",
|
||||
1007: "CORS Allow Origin Not Matching Origin",
|
||||
1008: "CORS Missing Allow Credentials",
|
||||
1009: "CORS Origin Header Missing",
|
||||
1010: "CORS External Redirect Not Allowed",
|
||||
1011: "CORS Preflight Did Not Succeed",
|
||||
1012: "CORS Invalid Allow Method",
|
||||
1013: "CORS Method Not Found",
|
||||
1014: "CORS Invalid Allow Header",
|
||||
1015: "CORS Missing Allow Header",
|
||||
2001: "Malware",
|
||||
2002: "Phishing",
|
||||
2003: "Unwanted",
|
||||
2004: "Tracking",
|
||||
2005: "Blocked",
|
||||
2006: "Harmful",
|
||||
3001: "Mixed Block",
|
||||
4000: "CSP",
|
||||
4001: "CSP No Data Protocol",
|
||||
4002: "CSP Web Extension",
|
||||
4003: "CSP ContentBlocked",
|
||||
4004: "CSP Data Document",
|
||||
4005: "CSP Web Browser",
|
||||
4006: "CSP Preload",
|
||||
};
|
||||
|
||||
const general = {
|
||||
ACTIVITY_TYPE,
|
||||
EVENTS,
|
||||
|
@ -415,6 +450,7 @@ const general = {
|
|||
MIN_COLUMN_WIDTH,
|
||||
DEFAULT_COLUMN_WIDTH,
|
||||
SUPPORTED_HTTP_CODES,
|
||||
BLOCKED_REASON_MESSAGES,
|
||||
};
|
||||
|
||||
// flatten constants
|
||||
|
|
|
@ -9,6 +9,7 @@ support-files =
|
|||
html_brotli-test-page.html
|
||||
html_image-tooltip-test-page.html
|
||||
html_cors-test-page.html
|
||||
html_csp-test-page.html
|
||||
html_custom-get-page.html
|
||||
html_cyrillic-test-page.html
|
||||
html_frame-test-page.html
|
||||
|
@ -77,6 +78,7 @@ support-files =
|
|||
[browser_net_background_update.js]
|
||||
[browser_net_autoscroll.js]
|
||||
[browser_net_block.js]
|
||||
[browser_net_block-csp.js]
|
||||
[browser_net_cached-status.js]
|
||||
skip-if = verify
|
||||
[browser_net_cause.js]
|
||||
|
@ -223,6 +225,7 @@ skip-if = true # TODO: fix the test
|
|||
[browser_net_timing-division.js]
|
||||
[browser_net_tracking-resources.js]
|
||||
[browser_net_truncate-post-data.js]
|
||||
skip-if = (os == 'win' && os_version == '6.1' && !debug) # Bug 1547150
|
||||
[browser_net_truncate.js]
|
||||
[browser_net_view-source-debugger.js]
|
||||
[browser_net_waterfall-click.js]
|
||||
|
|
|
@ -0,0 +1,43 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
/**
|
||||
* Test that CSP violations display in the netmonitor when blocked
|
||||
*/
|
||||
|
||||
add_task(async function() {
|
||||
const { tab, monitor } = await initNetMonitor(CSP_URL);
|
||||
|
||||
const { document, store, windowRequire } = monitor.panelWin;
|
||||
const Actions = windowRequire("devtools/client/netmonitor/src/actions/index");
|
||||
const {
|
||||
getDisplayedRequests,
|
||||
getSortedRequests,
|
||||
} = windowRequire("devtools/client/netmonitor/src/selectors/index");
|
||||
|
||||
store.dispatch(Actions.batchEnable(false));
|
||||
|
||||
tab.linkedBrowser.reload();
|
||||
|
||||
await waitForNetworkEvents(monitor, 2);
|
||||
|
||||
info("Waiting until the requests appear in netmonitor");
|
||||
|
||||
// Ensure the attempt to load a JS file shows a blocked CSP error
|
||||
verifyRequestItemTarget(
|
||||
document,
|
||||
getDisplayedRequests(store.getState()),
|
||||
getSortedRequests(store.getState()).get(1),
|
||||
"GET",
|
||||
EXAMPLE_URL + "js_websocket-worker-test.js",
|
||||
{
|
||||
transferred: "CSP Preload",
|
||||
cause: { type: "script" },
|
||||
type: "",
|
||||
}
|
||||
);
|
||||
|
||||
await teardown(monitor);
|
||||
});
|
|
@ -87,13 +87,13 @@ add_task(async function() {
|
|||
}
|
||||
|
||||
ok(!normalRequestState.blockedReason, "Normal request is not blocked");
|
||||
ok(!normalRequestSize.includes("blocked"), "Normal request has a size");
|
||||
ok(!normalRequestSize.includes("Blocked"), "Normal request has a size");
|
||||
|
||||
ok(blockedRequestState.blockedReason, "Blocked request is blocked");
|
||||
ok(blockedRequestSize.includes("blocked"), "Blocked request shows reason as size");
|
||||
ok(blockedRequestSize.includes("Blocked"), "Blocked request shows reason as size");
|
||||
|
||||
ok(!unblockedRequestState.blockedReason, "Unblocked request is not blocked");
|
||||
ok(!unblockedRequestSize.includes("blocked"), "Unblocked request has a size");
|
||||
ok(!unblockedRequestSize.includes("Blocked"), "Unblocked request has a size");
|
||||
|
||||
return teardown(monitor);
|
||||
});
|
||||
|
|
|
@ -78,6 +78,7 @@ const SEND_BEACON_URL = EXAMPLE_URL + "html_send-beacon.html";
|
|||
const CORS_URL = EXAMPLE_URL + "html_cors-test-page.html";
|
||||
const PAUSE_URL = EXAMPLE_URL + "html_pause-test-page.html";
|
||||
const OPEN_REQUEST_IN_TAB_URL = EXAMPLE_URL + "html_open-request-in-tab.html";
|
||||
const CSP_URL = EXAMPLE_URL + "html_csp-test-page.html";
|
||||
|
||||
const SIMPLE_SJS = EXAMPLE_URL + "sjs_simple-test-server.sjs";
|
||||
const SIMPLE_UNSORTED_COOKIES_SJS = EXAMPLE_URL + "sjs_simple-unsorted-cookies-test-server.sjs";
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset=utf-8>
|
||||
<meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate" />
|
||||
<meta http-equiv="Pragma" content="no-cache" />
|
||||
<meta http-equiv="Expires" content="0" />
|
||||
<meta http-equiv="Content-Security-Policy" content="script-src 'none';">
|
||||
<title>Tests breaking CSP with script</title>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
The script in this page will CSP:
|
||||
|
||||
<script src="js_websocket-worker-test.js"></script>
|
||||
</body>
|
||||
</html>
|
|
@ -262,12 +262,12 @@ NetworkObserver.prototype = {
|
|||
}
|
||||
|
||||
const channel = subject.QueryInterface(Ci.nsIHttpChannel);
|
||||
|
||||
if (!matchRequest(channel, this.filters)) {
|
||||
return;
|
||||
}
|
||||
|
||||
"add your handling code here";
|
||||
const blockedCode = channel.loadInfo.requestBlockingReason;
|
||||
this._httpResponseExaminer(subject, topic, blockedCode);
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -279,7 +279,7 @@ NetworkObserver.prototype = {
|
|||
* @param string topic
|
||||
* @returns void
|
||||
*/
|
||||
_httpResponseExaminer: function(subject, topic) {
|
||||
_httpResponseExaminer: function(subject, topic, blockedReason) {
|
||||
// The httpResponseExaminer is used to retrieve the uncached response
|
||||
// headers. The data retrieved is stored in openResponses. The
|
||||
// NetworkResponseListener is responsible with updating the httpActivity
|
||||
|
@ -287,7 +287,8 @@ NetworkObserver.prototype = {
|
|||
|
||||
if (!this.owner ||
|
||||
(topic != "http-on-examine-response" &&
|
||||
topic != "http-on-examine-cached-response") ||
|
||||
topic != "http-on-examine-cached-response" &&
|
||||
topic != "http-on-failed-opening-request") ||
|
||||
!(subject instanceof Ci.nsIHttpChannel)) {
|
||||
return;
|
||||
}
|
||||
|
@ -307,26 +308,28 @@ NetworkObserver.prototype = {
|
|||
|
||||
const setCookieHeaders = [];
|
||||
|
||||
channel.visitOriginalResponseHeaders({
|
||||
visitHeader: function(name, value) {
|
||||
const lowerName = name.toLowerCase();
|
||||
if (lowerName == "set-cookie") {
|
||||
setCookieHeaders.push(value);
|
||||
}
|
||||
response.headers.push({ name: name, value: value });
|
||||
},
|
||||
});
|
||||
if (!blockedReason) {
|
||||
channel.visitOriginalResponseHeaders({
|
||||
visitHeader: function(name, value) {
|
||||
const lowerName = name.toLowerCase();
|
||||
if (lowerName == "set-cookie") {
|
||||
setCookieHeaders.push(value);
|
||||
}
|
||||
response.headers.push({ name: name, value: value });
|
||||
},
|
||||
});
|
||||
|
||||
if (!response.headers.length) {
|
||||
// No need to continue.
|
||||
return;
|
||||
}
|
||||
if (!response.headers.length) {
|
||||
// No need to continue.
|
||||
return;
|
||||
}
|
||||
|
||||
if (setCookieHeaders.length) {
|
||||
response.cookies = setCookieHeaders.reduce((result, header) => {
|
||||
const cookies = NetworkHelper.parseSetCookieHeader(header);
|
||||
return result.concat(cookies);
|
||||
}, []);
|
||||
if (setCookieHeaders.length) {
|
||||
response.cookies = setCookieHeaders.reduce((result, header) => {
|
||||
const cookies = NetworkHelper.parseSetCookieHeader(header);
|
||||
return result.concat(cookies);
|
||||
}, []);
|
||||
}
|
||||
}
|
||||
|
||||
// Determine the HTTP version.
|
||||
|
@ -334,14 +337,16 @@ NetworkObserver.prototype = {
|
|||
const httpVersionMin = {};
|
||||
|
||||
channel.QueryInterface(Ci.nsIHttpChannelInternal);
|
||||
channel.getResponseVersion(httpVersionMaj, httpVersionMin);
|
||||
if (!blockedReason) {
|
||||
channel.getResponseVersion(httpVersionMaj, httpVersionMin);
|
||||
|
||||
response.status = channel.responseStatus;
|
||||
response.statusText = channel.responseStatusText;
|
||||
response.httpVersion = "HTTP/" + httpVersionMaj.value + "." +
|
||||
response.status = channel.responseStatus;
|
||||
response.statusText = channel.responseStatusText;
|
||||
response.httpVersion = "HTTP/" + httpVersionMaj.value + "." +
|
||||
httpVersionMin.value;
|
||||
|
||||
this.openResponses.set(channel, response);
|
||||
this.openResponses.set(channel, response);
|
||||
}
|
||||
|
||||
if (topic === "http-on-examine-cached-response") {
|
||||
// Service worker requests emits cached-response notification on non-e10s,
|
||||
|
@ -370,6 +375,8 @@ NetworkObserver.prototype = {
|
|||
const timings = this._setupHarTimings(httpActivity, true);
|
||||
httpActivity.owner.addEventTimings(timings.total, timings.timings,
|
||||
timings.offsets);
|
||||
} else if (topic === "http-on-failed-opening-request") {
|
||||
this._createNetworkEvent(channel, {blockedReason});
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -506,7 +513,8 @@ NetworkObserver.prototype = {
|
|||
*
|
||||
*/
|
||||
_createNetworkEvent: function(channel, { timestamp, extraStringData,
|
||||
fromCache, fromServiceWorker }) {
|
||||
fromCache, fromServiceWorker,
|
||||
blockedReason }) {
|
||||
const httpActivity = this.createOrGetActivityObject(channel);
|
||||
|
||||
channel.QueryInterface(Ci.nsIPrivateBrowsingChannel);
|
||||
|
@ -596,9 +604,13 @@ NetworkObserver.prototype = {
|
|||
|
||||
// Check the request URL with ones manually blocked by the user in DevTools.
|
||||
// If it's meant to be blocked, we cancel the request and annotate the event.
|
||||
if (this.blockedURLs.has(httpActivity.url)) {
|
||||
channel.cancel(Cr.NS_BINDING_ABORTED);
|
||||
event.blockedReason = "DevTools";
|
||||
if (!blockedReason) {
|
||||
if (this.blockedURLs.has(httpActivity.url)) {
|
||||
channel.cancel(Cr.NS_BINDING_ABORTED);
|
||||
event.blockedReason = "devtools";
|
||||
}
|
||||
} else {
|
||||
event.blockedReason = blockedReason;
|
||||
}
|
||||
|
||||
httpActivity.owner = this.owner.onNetworkEvent(event);
|
||||
|
|
|
@ -138,9 +138,14 @@ class InactivePropertyHelper {
|
|||
"vertical-align",
|
||||
],
|
||||
when: () => {
|
||||
return !this.checkStyle("display", ["inline", "table-cell"]) &&
|
||||
!this.cssRule.selectorText.includes("::first-letter") &&
|
||||
!this.cssRule.selectorText.includes("::first-line");
|
||||
const { selectorText } = this.cssRule;
|
||||
|
||||
const isFirstLetter = selectorText && selectorText.includes("::first-letter");
|
||||
const isFirstLine = selectorText && selectorText.includes("::first-line");
|
||||
|
||||
const isInlineLevel = this.checkStyle("display", ["inline", "table-cell"]);
|
||||
|
||||
return !isInlineLevel && !isFirstLetter && !isFirstLine;
|
||||
},
|
||||
fixId: "inactive-css-not-inline-or-tablecell-fix",
|
||||
msgId: "inactive-css-not-inline-or-tablecell",
|
||||
|
|
|
@ -126,7 +126,7 @@ skip-if = e10s # Bug 1183605 - devtools/server/tests/browser/ tests are still di
|
|||
[browser_storage_dynamic_windows.js]
|
||||
[browser_storage_listings.js]
|
||||
[browser_storage_updates.js]
|
||||
skip-if = (verify && debug && (os == 'mac' || os == 'linux'))
|
||||
skip-if = (verify && debug && (os == 'mac' || os == 'linux')) || (os == 'win' && debug) # Bug 1493369
|
||||
[browser_stylesheets_getTextEmpty.js]
|
||||
[browser_stylesheets_nested-iframes.js]
|
||||
[browser_register_actor.js]
|
||||
|
|
|
@ -341,12 +341,7 @@ void BrowsingContext::RestoreChildren(Children&& aChildren, bool aFromIPC) {
|
|||
if (!aFromIPC && XRE_IsContentProcess()) {
|
||||
auto cc = ContentChild::GetSingleton();
|
||||
MOZ_DIAGNOSTIC_ASSERT(cc);
|
||||
|
||||
nsTArray<BrowsingContextId> contexts(aChildren.Length());
|
||||
for (BrowsingContext* child : aChildren) {
|
||||
contexts.AppendElement(child->Id());
|
||||
}
|
||||
cc->SendRestoreBrowsingContextChildren(this, contexts);
|
||||
cc->SendRestoreBrowsingContextChildren(this, aChildren);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -190,25 +190,6 @@ void DOMIntersectionObserver::TakeRecords(
|
|||
mQueuedEntries.Clear();
|
||||
}
|
||||
|
||||
static bool CheckSimilarOrigin(nsINode* aNode1, nsINode* aNode2) {
|
||||
nsIPrincipal* principal1 = aNode1->NodePrincipal();
|
||||
nsIPrincipal* principal2 = aNode2->NodePrincipal();
|
||||
nsAutoCString baseDomain1;
|
||||
nsAutoCString baseDomain2;
|
||||
|
||||
nsresult rv = principal1->GetBaseDomain(baseDomain1);
|
||||
if (NS_FAILED(rv)) {
|
||||
return principal1 == principal2;
|
||||
}
|
||||
|
||||
rv = principal2->GetBaseDomain(baseDomain2);
|
||||
if (NS_FAILED(rv)) {
|
||||
return principal1 == principal2;
|
||||
}
|
||||
|
||||
return baseDomain1 == baseDomain2;
|
||||
}
|
||||
|
||||
static Maybe<nsRect> EdgeInclusiveIntersection(const nsRect& aRect,
|
||||
const nsRect& aOtherRect) {
|
||||
nscoord left = std::max(aRect.x, aOtherRect.x);
|
||||
|
@ -221,22 +202,41 @@ static Maybe<nsRect> EdgeInclusiveIntersection(const nsRect& aRect,
|
|||
return Some(nsRect(left, top, right - left, bottom - top));
|
||||
}
|
||||
|
||||
enum class BrowsingContextInfo {
|
||||
SimilarOriginBrowsingContext,
|
||||
DifferentOriginBrowsingContext,
|
||||
UnknownBrowsingContext
|
||||
};
|
||||
enum class BrowsingContextOrigin { Similar, Different, Unknown };
|
||||
|
||||
// FIXME(emilio): The whole concept of "units of related similar-origin browsing
|
||||
// contexts" is gone, but this is still in the spec, see
|
||||
// https://github.com/w3c/IntersectionObserver/issues/161
|
||||
static BrowsingContextOrigin SimilarOrigin(const Element& aTarget,
|
||||
const Element* aRoot) {
|
||||
if (!aRoot) {
|
||||
return BrowsingContextOrigin::Unknown;
|
||||
}
|
||||
nsIPrincipal* principal1 = aTarget.NodePrincipal();
|
||||
nsIPrincipal* principal2 = aRoot->NodePrincipal();
|
||||
|
||||
if (principal1 == principal2) {
|
||||
return BrowsingContextOrigin::Similar;
|
||||
}
|
||||
|
||||
nsAutoCString baseDomain1;
|
||||
nsAutoCString baseDomain2;
|
||||
if (NS_FAILED(principal1->GetBaseDomain(baseDomain1)) ||
|
||||
NS_FAILED(principal2->GetBaseDomain(baseDomain2))) {
|
||||
return BrowsingContextOrigin::Different;
|
||||
}
|
||||
|
||||
return baseDomain1 == baseDomain2 ? BrowsingContextOrigin::Similar
|
||||
: BrowsingContextOrigin::Different;
|
||||
}
|
||||
|
||||
void DOMIntersectionObserver::Update(Document* aDocument,
|
||||
DOMHighResTimeStamp time) {
|
||||
Element* root = nullptr;
|
||||
nsIFrame* rootFrame = nullptr;
|
||||
nsRect rootRect;
|
||||
|
||||
nsIFrame* rootFrame = nullptr;
|
||||
Element* root = mRoot;
|
||||
if (mRoot) {
|
||||
root = mRoot;
|
||||
rootFrame = root->GetPrimaryFrame();
|
||||
if (rootFrame) {
|
||||
if ((rootFrame = mRoot->GetPrimaryFrame())) {
|
||||
nsRect rootRectRelativeToRootFrame;
|
||||
if (rootFrame->IsScrollFrame()) {
|
||||
// rootRectRelativeToRootFrame should be the content rect of rootFrame,
|
||||
|
@ -252,33 +252,28 @@ void DOMIntersectionObserver::Update(Document* aDocument,
|
|||
rootRect = nsLayoutUtils::TransformFrameRectToAncestor(
|
||||
rootFrame, rootRectRelativeToRootFrame, containingBlock);
|
||||
}
|
||||
} else {
|
||||
RefPtr<PresShell> presShell = aDocument->GetPresShell();
|
||||
if (presShell) {
|
||||
rootFrame = presShell->GetRootScrollFrame();
|
||||
if (rootFrame) {
|
||||
nsPresContext* presContext = rootFrame->PresContext();
|
||||
while (!presContext->IsRootContentDocument()) {
|
||||
presContext = presContext->GetParentPresContext();
|
||||
if (!presContext) {
|
||||
break;
|
||||
}
|
||||
nsIFrame* rootScrollFrame =
|
||||
presContext->PresShell()->GetRootScrollFrame();
|
||||
if (rootScrollFrame) {
|
||||
rootFrame = rootScrollFrame;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
} else if (PresShell* presShell = aDocument->GetPresShell()) {
|
||||
// FIXME(emilio): This shouldn't probably go through the presShell and just
|
||||
// through the document tree.
|
||||
rootFrame = presShell->GetRootScrollFrame();
|
||||
if (rootFrame) {
|
||||
nsPresContext* presContext = rootFrame->PresContext();
|
||||
while (!presContext->IsRootContentDocument()) {
|
||||
presContext = presContext->GetParentPresContext();
|
||||
if (!presContext) {
|
||||
break;
|
||||
}
|
||||
root = rootFrame->GetContent()->AsElement();
|
||||
nsIScrollableFrame* scrollFrame = do_QueryFrame(rootFrame);
|
||||
// If we end up with a null root frame for some reason, we'll proceed
|
||||
// with an empty root intersection rect.
|
||||
if (scrollFrame) {
|
||||
rootRect = scrollFrame->GetScrollPortRect();
|
||||
nsIFrame* rootScrollFrame =
|
||||
presContext->PresShell()->GetRootScrollFrame();
|
||||
if (rootScrollFrame) {
|
||||
rootFrame = rootScrollFrame;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
root = rootFrame->GetContent()->AsElement();
|
||||
nsIScrollableFrame* scrollFrame = do_QueryFrame(rootFrame);
|
||||
rootRect = scrollFrame->GetScrollPortRect();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -290,8 +285,7 @@ void DOMIntersectionObserver::Update(Document* aDocument,
|
|||
nsLayoutUtils::ComputeCBDependentValue(basis, mRootMargin.Get(side));
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < mObservationTargets.Length(); ++i) {
|
||||
Element* target = mObservationTargets.ElementAt(i);
|
||||
for (Element* target : mObservationTargets) {
|
||||
nsIFrame* targetFrame = target->GetPrimaryFrame();
|
||||
nsIFrame* originalTargetFrame = targetFrame;
|
||||
nsRect targetRect;
|
||||
|
@ -347,22 +341,13 @@ void DOMIntersectionObserver::Update(Document* aDocument,
|
|||
}
|
||||
|
||||
nsRect rootIntersectionRect;
|
||||
BrowsingContextInfo isInSimilarOriginBrowsingContext =
|
||||
BrowsingContextInfo::UnknownBrowsingContext;
|
||||
|
||||
if (rootFrame && targetFrame) {
|
||||
// FIXME(emilio): Why only if there are frames?
|
||||
rootIntersectionRect = rootRect;
|
||||
}
|
||||
|
||||
if (root && target) {
|
||||
isInSimilarOriginBrowsingContext =
|
||||
CheckSimilarOrigin(root, target)
|
||||
? BrowsingContextInfo::SimilarOriginBrowsingContext
|
||||
: BrowsingContextInfo::DifferentOriginBrowsingContext;
|
||||
}
|
||||
|
||||
if (isInSimilarOriginBrowsingContext ==
|
||||
BrowsingContextInfo::SimilarOriginBrowsingContext) {
|
||||
BrowsingContextOrigin origin = SimilarOrigin(*target, root);
|
||||
if (origin == BrowsingContextOrigin::Similar) {
|
||||
rootIntersectionRect.Inflate(rootMargin);
|
||||
}
|
||||
|
||||
|
@ -416,13 +401,12 @@ void DOMIntersectionObserver::Update(Document* aDocument,
|
|||
}
|
||||
|
||||
if (target->UpdateIntersectionObservation(this, threshold)) {
|
||||
QueueIntersectionObserverEntry(
|
||||
target, time,
|
||||
isInSimilarOriginBrowsingContext ==
|
||||
BrowsingContextInfo::DifferentOriginBrowsingContext
|
||||
? Nothing()
|
||||
: Some(rootIntersectionRect),
|
||||
targetRect, intersectionRect, intersectionRatio);
|
||||
QueueIntersectionObserverEntry(target, time,
|
||||
origin == BrowsingContextOrigin::Different
|
||||
? Nothing()
|
||||
: Some(rootIntersectionRect),
|
||||
targetRect, intersectionRect,
|
||||
intersectionRatio);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5845,7 +5845,7 @@ nsresult nsContentUtils::GetThreadSafeASCIIOrigin(nsIURI* aURI,
|
|||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCOMPtr<nsIURI> uri;
|
||||
nsresult rv = NS_NewURIOnAnyThread(getter_AddRefs(uri), path);
|
||||
nsresult rv = NS_NewURI(getter_AddRefs(uri), path);
|
||||
if (rv == NS_ERROR_UNKNOWN_PROTOCOL) {
|
||||
return NS_ERROR_UNKNOWN_PROTOCOL;
|
||||
}
|
||||
|
|
|
@ -2605,7 +2605,7 @@ bool nsFrameLoader::TryRemoteBrowserInternal() {
|
|||
RefPtr<ContentParent> openerContentParent;
|
||||
RefPtr<BrowserParent> sameTabGroupAs;
|
||||
if (auto* host = BrowserHost::GetFrom(parentDocShell->GetOpener())) {
|
||||
openerContentParent = host->GetActor()->Manager();
|
||||
openerContentParent = host->GetContentParent();
|
||||
}
|
||||
|
||||
// <iframe mozbrowser> gets to skip these checks.
|
||||
|
|
|
@ -18,6 +18,9 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=682305
|
|||
</div>
|
||||
<pre id="test">
|
||||
<script class="testbody" type="application/javascript">
|
||||
|
||||
"use strict";
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
/*
|
||||
|
@ -107,12 +110,6 @@ CustomProtocol.prototype = {
|
|||
allowPort: function allowPort() {
|
||||
return false;
|
||||
},
|
||||
newURI: function newURI(spec, charset, baseURI) {
|
||||
return Cc["@mozilla.org/network/simple-uri-mutator;1"]
|
||||
.createInstance(Ci.nsIURIMutator)
|
||||
.setSpec(spec)
|
||||
.finalize();
|
||||
},
|
||||
newChannel: function newChannel(URI, loadInfo) {
|
||||
return new CustomChannel(URI, loadInfo);
|
||||
},
|
||||
|
|
|
@ -777,13 +777,6 @@ BlobURLProtocolHandler::GetFlagsForURI(nsIURI* aURI, uint32_t* aResult) {
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
BlobURLProtocolHandler::NewURI(const nsACString& aSpec, const char* aCharset,
|
||||
nsIURI* aBaseURI, nsIURI** aResult) {
|
||||
return BlobURLProtocolHandler::CreateNewURI(aSpec, aCharset, aBaseURI,
|
||||
aResult);
|
||||
}
|
||||
|
||||
/* static */ nsresult BlobURLProtocolHandler::CreateNewURI(
|
||||
const nsACString& aSpec, const char* aCharset, nsIURI* aBaseURI,
|
||||
nsIURI** aResult) {
|
||||
|
|
|
@ -77,35 +77,3 @@ FontTableURIProtocolHandler::GetScheme(nsACString& result) {
|
|||
result.AssignLiteral(FONTTABLEURI_SCHEME);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
FontTableURIProtocolHandler::NewURI(const nsACString& aSpec,
|
||||
const char* aCharset, nsIURI* aBaseURI,
|
||||
nsIURI** aResult) {
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIURI> uri;
|
||||
|
||||
// Either you got here via a ref or a fonttable: uri
|
||||
if (aSpec.Length() && aSpec.CharAt(0) == '#') {
|
||||
rv = NS_MutateURI(aBaseURI).SetRef(aSpec).Finalize(uri);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
} else {
|
||||
// Relative URIs (other than #ref) are not meaningful within the
|
||||
// fonttable: scheme.
|
||||
// If aSpec is a relative URI -other- than a bare #ref,
|
||||
// this will leave uri empty, and we'll return a failure code below.
|
||||
rv = NS_MutateURI(new mozilla::net::nsSimpleURI::Mutator())
|
||||
.SetSpec(aSpec)
|
||||
.Finalize(uri);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
bool schemeIs;
|
||||
if (NS_FAILED(uri->SchemeIs(FONTTABLEURI_SCHEME, &schemeIs)) || !schemeIs) {
|
||||
NS_WARNING("Non-fonttable spec in FontTableURIProtocolHandler");
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
uri.forget(aResult);
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
|
@ -3844,17 +3844,10 @@ mozilla::ipc::IPCResult ContentChild::RecvCacheBrowsingContextChildren(
|
|||
}
|
||||
|
||||
mozilla::ipc::IPCResult ContentChild::RecvRestoreBrowsingContextChildren(
|
||||
BrowsingContext* aContext, nsTArray<BrowsingContextId>&& aChildren) {
|
||||
BrowsingContext* aContext, BrowsingContext::Children&& aChildren) {
|
||||
MOZ_DIAGNOSTIC_ASSERT(aContext);
|
||||
|
||||
BrowsingContext::Children children(aChildren.Length());
|
||||
|
||||
for (auto id : aChildren) {
|
||||
RefPtr<BrowsingContext> child = BrowsingContext::Get(id);
|
||||
children.AppendElement(child);
|
||||
}
|
||||
|
||||
aContext->RestoreChildren(std::move(children), /* aFromIPC */ true);
|
||||
aContext->RestoreChildren(std::move(aChildren), /* aFromIPC */ true);
|
||||
|
||||
return IPC_OK();
|
||||
}
|
||||
|
|
|
@ -722,7 +722,7 @@ class ContentChild final : public PContentChild,
|
|||
BrowsingContext* aContext);
|
||||
|
||||
mozilla::ipc::IPCResult RecvRestoreBrowsingContextChildren(
|
||||
BrowsingContext* aContext, nsTArray<BrowsingContextId>&& aChildren);
|
||||
BrowsingContext* aContext, BrowsingContext::Children&& aChildren);
|
||||
|
||||
mozilla::ipc::IPCResult RecvRegisterBrowsingContextGroup(
|
||||
nsTArray<BrowsingContext::IPCInitializer>&& aInits);
|
||||
|
|
|
@ -5820,7 +5820,7 @@ mozilla::ipc::IPCResult ContentParent::RecvCacheBrowsingContextChildren(
|
|||
}
|
||||
|
||||
mozilla::ipc::IPCResult ContentParent::RecvRestoreBrowsingContextChildren(
|
||||
BrowsingContext* aContext, nsTArray<BrowsingContextId>&& aChildren) {
|
||||
BrowsingContext* aContext, BrowsingContext::Children&& aChildren) {
|
||||
if (!aContext) {
|
||||
MOZ_LOG(BrowsingContext::GetLog(), LogLevel::Debug,
|
||||
("ParentIPC: Trying to restore already detached"));
|
||||
|
@ -5840,14 +5840,7 @@ mozilla::ipc::IPCResult ContentParent::RecvRestoreBrowsingContextChildren(
|
|||
return IPC_OK();
|
||||
}
|
||||
|
||||
BrowsingContext::Children children(aChildren.Length());
|
||||
|
||||
for (auto id : aChildren) {
|
||||
RefPtr<BrowsingContext> child = BrowsingContext::Get(id);
|
||||
children.AppendElement(child);
|
||||
}
|
||||
|
||||
aContext->RestoreChildren(std::move(children), /* aFromIPC */ true);
|
||||
aContext->RestoreChildren(std::move(aChildren), /* aFromIPC */ true);
|
||||
|
||||
aContext->Group()->EachOtherParent(this, [&](ContentParent* aParent) {
|
||||
Unused << aParent->SendRestoreBrowsingContextChildren(aContext, aChildren);
|
||||
|
|
|
@ -629,7 +629,7 @@ class ContentParent final : public PContentParent,
|
|||
BrowsingContext* aContext);
|
||||
|
||||
mozilla::ipc::IPCResult RecvRestoreBrowsingContextChildren(
|
||||
BrowsingContext* aContext, nsTArray<BrowsingContextId>&& aChildren);
|
||||
BrowsingContext* aContext, BrowsingContext::Children&& aChildren);
|
||||
|
||||
mozilla::ipc::IPCResult RecvWindowClose(BrowsingContext* aContext,
|
||||
bool aTrustedCaller);
|
||||
|
|
|
@ -43,7 +43,6 @@ class IdType {
|
|||
|
||||
typedef IdType<BrowserParent> TabId;
|
||||
typedef IdType<ContentParent> ContentParentId;
|
||||
typedef IdType<BrowsingContext> BrowsingContextId;
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
||||
|
|
|
@ -97,7 +97,6 @@ using mozilla::Telemetry::DiscardedData from "mozilla/TelemetryComms.h";
|
|||
using mozilla::CrossProcessMutexHandle from "mozilla/ipc/CrossProcessMutex.h";
|
||||
using refcounted class nsIInputStream from "mozilla/ipc/IPCStreamUtils.h";
|
||||
using refcounted class mozilla::dom::BrowsingContext from "mozilla/dom/BrowsingContext.h";
|
||||
using mozilla::dom::BrowsingContextId from "mozilla/dom/ipc/IdType.h";
|
||||
using mozilla::dom::BrowsingContextTransaction from "mozilla/dom/BrowsingContext.h";
|
||||
using mozilla::dom::BrowsingContextFieldEpochs from "mozilla/dom/BrowsingContext.h";
|
||||
using mozilla::dom::BrowsingContextInitializer from "mozilla/dom/BrowsingContext.h";
|
||||
|
@ -1450,7 +1449,7 @@ both:
|
|||
* Re-attach all BrowsingContexts in a 'aContext'.
|
||||
*/
|
||||
async RestoreBrowsingContextChildren(BrowsingContext aContext,
|
||||
BrowsingContextId[] aChildren);
|
||||
BrowsingContext[] aChildren);
|
||||
|
||||
async WindowClose(BrowsingContext aContext, bool aTrustedCaller);
|
||||
async WindowFocus(BrowsingContext aContext);
|
||||
|
|
|
@ -1106,11 +1106,6 @@ nsJSProtocolHandler::GetProtocolFlags(uint32_t* result) {
|
|||
URI_OPENING_EXECUTES_SCRIPT;
|
||||
return NS_OK;
|
||||
}
|
||||
NS_IMETHODIMP
|
||||
nsJSProtocolHandler::NewURI(const nsACString& aSpec, const char* aCharset,
|
||||
nsIURI* aBaseURI, nsIURI** result) {
|
||||
return nsJSProtocolHandler::CreateNewURI(aSpec, aCharset, aBaseURI, result);
|
||||
}
|
||||
|
||||
/* static */ nsresult nsJSProtocolHandler::CreateNewURI(const nsACString& aSpec,
|
||||
const char* aCharset,
|
||||
|
|
|
@ -138,11 +138,9 @@ already_AddRefed<MediaRawData> SampleIterator::GetNext() {
|
|||
if (moofParser->mSinf.mDefaultEncryptionType == AtomType("cenc")) {
|
||||
cryptoScheme = CryptoScheme::Cenc;
|
||||
writer->mCrypto.mCryptoScheme = CryptoScheme::Cenc;
|
||||
writer->mCrypto.mInitDataType = NS_LITERAL_STRING("cenc");
|
||||
} else if (moofParser->mSinf.mDefaultEncryptionType == AtomType("cbcs")) {
|
||||
cryptoScheme = CryptoScheme::Cbcs;
|
||||
writer->mCrypto.mCryptoScheme = CryptoScheme::Cbcs;
|
||||
writer->mCrypto.mInitDataType = NS_LITERAL_STRING("cenc");
|
||||
} else {
|
||||
MOZ_ASSERT_UNREACHABLE(
|
||||
"Sample description entry reports sample is encrypted, but no "
|
||||
|
@ -151,17 +149,18 @@ already_AddRefed<MediaRawData> SampleIterator::GetNext() {
|
|||
}
|
||||
}
|
||||
|
||||
// We need to check if this moof has init data the CDM expects us to surface.
|
||||
// This should happen when handling the first sample, even if that sample
|
||||
// isn't encrypted (samples later in the moof may be).
|
||||
if (mCurrentSample == 0) {
|
||||
const nsTArray<Moof>& moofs = moofParser->Moofs();
|
||||
const Moof* currentMoof = &moofs[mCurrentMoof];
|
||||
if (!currentMoof->mPsshes.IsEmpty()) {
|
||||
MOZ_ASSERT(sampleDescriptionEntry->mIsEncryptedEntry,
|
||||
"Unencrypted fragments should not contain pssh boxes");
|
||||
MOZ_ASSERT(cryptoScheme != CryptoScheme::None);
|
||||
// This Moof contained crypto init data. Report that. We only report
|
||||
// the init data on the Moof's first sample, to avoid reporting it more
|
||||
// than once per Moof.
|
||||
writer->mCrypto.mInitDatas.AppendElements(currentMoof->mPsshes);
|
||||
writer->mCrypto.mInitDataType = NS_LITERAL_STRING("cenc");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Двоичный файл не отображается.
|
@ -0,0 +1 @@
|
|||
Cache-Control: no-store
|
Двоичный файл не отображается.
|
@ -0,0 +1 @@
|
|||
Cache-Control: no-store
|
|
@ -79,6 +79,10 @@ support-files =
|
|||
bipbop-cenc-videoinit.mp4^headers^
|
||||
bipbop-cenc-video-10s.mp4
|
||||
bipbop-cenc-video-10s.mp4^headers^
|
||||
bipbop-clearkey-keyrotation-clear-lead-audio.mp4
|
||||
bipbop-clearkey-keyrotation-clear-lead-audio.mp4^headers^
|
||||
bipbop-clearkey-keyrotation-clear-lead-video.mp4
|
||||
bipbop-clearkey-keyrotation-clear-lead-video.mp4^headers^
|
||||
bipbop_225w_175kbps.mp4
|
||||
bipbop_225w_175kbps.mp4^headers^
|
||||
bipbop_225w_175kbps-cenc-audio-key1-1.m4s
|
||||
|
|
|
@ -10,64 +10,84 @@
|
|||
</head>
|
||||
|
||||
<body>
|
||||
<video controls id="video"></video>
|
||||
<div id="log"></div>
|
||||
<script class="testbody" type="text/javascript">
|
||||
let manager = new MediaTestManager;
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
let psshTests = [
|
||||
{ name: "bear-640x360-cenc-key-rotation",
|
||||
tracks : [
|
||||
{
|
||||
name: "video",
|
||||
type: "video/mp4; codecs=\"avc1.64000d\"",
|
||||
fragments: ["bear-640x360-v_frag-cenc-key_rotation.mp4"],
|
||||
initDatas: 6
|
||||
},
|
||||
{
|
||||
name: "audio",
|
||||
type: "audio/mp4; codecs=\"mp4a.40.2\"",
|
||||
fragments: ["bear-640x360-a_frag-cenc-key_rotation.mp4"],
|
||||
initDatas: 7
|
||||
}
|
||||
],
|
||||
keys : {
|
||||
"30313233343536373839303132333435" :
|
||||
"ebdd62f16814d27b68ef122afce4ae3c"
|
||||
}
|
||||
},
|
||||
{ name: "bipbop-clearkey-keyrotation-clear-lead",
|
||||
tracks : [
|
||||
{
|
||||
name: "video",
|
||||
type: "video/mp4; codecs=\"avc1.4d4015\"",
|
||||
fragments: ["bipbop-clearkey-keyrotation-clear-lead-video.mp4"],
|
||||
initDatas: 3
|
||||
},
|
||||
{
|
||||
name: "audio",
|
||||
type: "audio/mp4; codecs=\"mp4a.40.2\"",
|
||||
fragments: ["bipbop-clearkey-keyrotation-clear-lead-audio.mp4"],
|
||||
initDatas: 3
|
||||
}
|
||||
],
|
||||
keys : {
|
||||
"00112233445566778899aabbccddeeff" :
|
||||
"00112233445566778899aabbccddeeff",
|
||||
"112233445566778899aabbccddeeff00" :
|
||||
"112233445566778899aabbccddeeff00"
|
||||
}
|
||||
}
|
||||
];
|
||||
|
||||
function e(id) {
|
||||
return document.getElementById(id);
|
||||
// Specialized create media keys function, since the one in eme.js relies
|
||||
// on listening for encrypted events, and we want to manage those
|
||||
// ourselves within this test.
|
||||
async function createAndSetMediaKeys(video, test, token) {
|
||||
function streamType(type) {
|
||||
var x = test.tracks.find(o => o.name == type);
|
||||
return x ? x.type : undefined;
|
||||
}
|
||||
|
||||
function log(msg) {
|
||||
var log_pane = e('log');
|
||||
log_pane.appendChild(document.createTextNode(msg));
|
||||
log_pane.appendChild(document.createElement("br"));
|
||||
var configuration = { initDataTypes: ["cenc"] };
|
||||
if (streamType("video")) {
|
||||
configuration.videoCapabilities = [{contentType: streamType("video")}];
|
||||
}
|
||||
|
||||
function DownloadMedia(url, type, mediaSource) {
|
||||
return new Promise((resolve, reject) => {
|
||||
var sourceBuffer = mediaSource.addSourceBuffer(type);
|
||||
fetch(url)
|
||||
.then((response) => { return response.arrayBuffer(); })
|
||||
.then((arrayBuffer) => {
|
||||
once(sourceBuffer, "updateend", resolve);
|
||||
sourceBuffer.appendBuffer(arrayBuffer);
|
||||
});
|
||||
});
|
||||
if (streamType("audio")) {
|
||||
configuration.audioCapabilities = [{contentType: streamType("audio")}];
|
||||
}
|
||||
let keySystemAccess = await navigator.requestMediaKeySystemAccess(
|
||||
"org.w3.clearkey", [configuration]);
|
||||
let mediaKeys = await keySystemAccess.createMediaKeys();
|
||||
return video.setMediaKeys(mediaKeys);
|
||||
}
|
||||
|
||||
function LoadMSE(video, tracks) {
|
||||
var ms = new MediaSource();
|
||||
video.src = URL.createObjectURL(ms);
|
||||
once(ms, "sourceopen", () => {
|
||||
Promise.all(tracks.map(track => DownloadMedia(track.url, track.type, ms)))
|
||||
.then(() => {
|
||||
ms.endOfStream();
|
||||
})
|
||||
});
|
||||
}
|
||||
function startTest(test, token) {
|
||||
manager.started(token);
|
||||
let video = document.createElement("video");
|
||||
document.body.appendChild(video);
|
||||
|
||||
function CreateMediaKeys(video, configurations) {
|
||||
return navigator.requestMediaKeySystemAccess("org.w3.clearkey", configurations)
|
||||
.then((keySystemAccess) => {
|
||||
return keySystemAccess.createMediaKeys();
|
||||
}, bail("Failed to request key system access."))
|
||||
let encryptedEventCount = 0;
|
||||
|
||||
.then((mediaKeys) => {
|
||||
video.mediaKeys = mediaKeys;
|
||||
return video.setMediaKeys(mediaKeys);
|
||||
}, bail("Failed to set media keys."));
|
||||
}
|
||||
|
||||
var encryptedEventCount = 0;
|
||||
|
||||
var initDatas = new Map();
|
||||
|
||||
var keys = {
|
||||
"30313233343536373839303132333435" : "ebdd62f16814d27b68ef122afce4ae3c"
|
||||
};
|
||||
let initDatas = new Map();
|
||||
|
||||
function handleEncrypted(event) {
|
||||
// We get one 'encrypted' event for every run of contiguous PSSH boxes
|
||||
|
@ -77,65 +97,44 @@
|
|||
// data is also repeated.
|
||||
encryptedEventCount++;
|
||||
|
||||
var hexStr = StringToHex(new TextDecoder().decode(event.initData));
|
||||
let hexStr = StringToHex(new TextDecoder().decode(event.initData));
|
||||
if (initDatas.has(hexStr)) {
|
||||
// Already have a session for this.
|
||||
return;
|
||||
}
|
||||
initDatas.set(hexStr, session);
|
||||
|
||||
var initData = new Uint8Array(event.initData);
|
||||
log("encrypted event => len=" + initData.length + " " + hexStr);
|
||||
var session = event.target.mediaKeys.createSession();
|
||||
session.addEventListener("message", function(event) {
|
||||
event.target.update(GenerateClearKeyLicense(event.message, keys));
|
||||
let initData = new Uint8Array(event.initData);
|
||||
is(event.initDataType, "cenc", "'encrypted' event should have 'cenc' " +
|
||||
"initDataType");
|
||||
Log(token, "encrypted event => len=" + initData.length + " " + hexStr);
|
||||
let session = event.target.mediaKeys.createSession();
|
||||
initDatas.set(hexStr, session);
|
||||
session.addEventListener("message", event => {
|
||||
event.target.update(
|
||||
GenerateClearKeyLicense(event.message, test.keys));
|
||||
});
|
||||
|
||||
session.generateRequest(event.initDataType, event.initData);
|
||||
}
|
||||
|
||||
const videoContentType = "video/mp4; codecs=\"avc1.64000d\"";
|
||||
const audioContentType = "audio/mp4; codecs=\"mp4a.40.2\"";
|
||||
|
||||
var tracks = [
|
||||
{
|
||||
type: videoContentType,
|
||||
url: "bear-640x360-v_frag-cenc-key_rotation.mp4",
|
||||
initDatas: 6,
|
||||
},
|
||||
{
|
||||
type: audioContentType,
|
||||
url: "bear-640x360-a_frag-cenc-key_rotation.mp4",
|
||||
initDatas: 7,
|
||||
}
|
||||
];
|
||||
|
||||
var configurations = [{
|
||||
initDataTypes: ["cenc"],
|
||||
audioCapabilities: [{
|
||||
contentType: audioContentType
|
||||
}],
|
||||
videoCapabilities: [{
|
||||
contentType: videoContentType
|
||||
}]
|
||||
}];
|
||||
|
||||
var video = document.getElementById("video");
|
||||
|
||||
video.addEventListener("encrypted", handleEncrypted, false);
|
||||
|
||||
video.addEventListener("ended", ()=>{
|
||||
var expectedEncryptedEvents = tracks.reduce((sum, track) => sum += track.initDatas, 0);
|
||||
is(encryptedEventCount, expectedEncryptedEvents, "Should get one 'encrypted' event per run of contiguous PSSH boxes in media.");
|
||||
SimpleTest.finish();
|
||||
video.addEventListener("ended", () => {
|
||||
let expectedEncryptedEvents =
|
||||
test.tracks.reduce((sum, track) => sum += track.initDatas, 0);
|
||||
is(encryptedEventCount, expectedEncryptedEvents,
|
||||
"Should get one 'encrypted' event per run of contiguous PSSH " +
|
||||
"boxes in media.");
|
||||
manager.finished(token);
|
||||
});
|
||||
|
||||
video.autoplay = true;
|
||||
|
||||
CreateMediaKeys(video, configurations)
|
||||
.then(()=>{
|
||||
LoadMSE(video, tracks);
|
||||
});
|
||||
createAndSetMediaKeys(video, test, token)
|
||||
.then(() => LoadTest(test, video, token))
|
||||
}
|
||||
|
||||
manager.runTests(psshTests, startTest);
|
||||
|
||||
</script>
|
||||
</body>
|
||||
|
|
|
@ -37,18 +37,6 @@ NS_IMETHODIMP nsIndexedDBProtocolHandler::GetProtocolFlags(
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsIndexedDBProtocolHandler::NewURI(const nsACString& aSpec,
|
||||
const char* aOriginCharset,
|
||||
nsIURI* aBaseURI,
|
||||
nsIURI** _retval) {
|
||||
nsCOMPtr<nsIURI> baseURI(aBaseURI);
|
||||
return NS_MutateURI(new nsStandardURL::Mutator())
|
||||
.Apply(NS_MutatorMethod(
|
||||
&nsIStandardURLMutator::Init, nsIStandardURL::URLTYPE_AUTHORITY, 0,
|
||||
nsCString(aSpec), aOriginCharset, baseURI, nullptr))
|
||||
.Finalize(_retval);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsIndexedDBProtocolHandler::NewChannel(nsIURI* aURI, nsILoadInfo* aLoadInfo,
|
||||
nsIChannel** _retval) {
|
||||
|
|
|
@ -412,8 +412,8 @@ void URLWorker::Init(const nsAString& aURL, const Optional<nsAString>& aBase,
|
|||
bool useProxy = false;
|
||||
nsCOMPtr<nsIURI> baseURI;
|
||||
if (aBase.WasPassed()) {
|
||||
rv = NS_NewURIOnAnyThread(getter_AddRefs(baseURI),
|
||||
NS_ConvertUTF16toUTF8(aBase.Value()));
|
||||
rv = NS_NewURI(getter_AddRefs(baseURI),
|
||||
NS_ConvertUTF16toUTF8(aBase.Value()));
|
||||
if (NS_FAILED(rv)) {
|
||||
if (rv != NS_ERROR_UNKNOWN_PROTOCOL) {
|
||||
aRv.ThrowTypeError<MSG_INVALID_URL>(aBase.Value());
|
||||
|
@ -426,8 +426,8 @@ void URLWorker::Init(const nsAString& aURL, const Optional<nsAString>& aBase,
|
|||
// Let's see if we can parse aURI on this thread.
|
||||
nsCOMPtr<nsIURI> uri;
|
||||
if (!useProxy) {
|
||||
rv = NS_NewURIOnAnyThread(getter_AddRefs(uri), NS_ConvertUTF16toUTF8(aURL),
|
||||
nullptr, baseURI);
|
||||
rv = NS_NewURI(getter_AddRefs(uri), NS_ConvertUTF16toUTF8(aURL), nullptr,
|
||||
baseURI);
|
||||
if (NS_FAILED(rv)) {
|
||||
if (rv != NS_ERROR_UNKNOWN_PROTOCOL) {
|
||||
aRv.ThrowTypeError<MSG_INVALID_URL>(aURL);
|
||||
|
|
|
@ -426,7 +426,7 @@
|
|||
is(url.href, "ftp://tmp/test");
|
||||
|
||||
url = new URL("scheme://tmp\\test", base);
|
||||
is(url.href, "scheme://tmp\\test");
|
||||
is(url.href, "scheme://tmp/test");
|
||||
</script>
|
||||
|
||||
<script>
|
||||
|
|
|
@ -17,6 +17,10 @@ FINAL_LIBRARY = 'xul'
|
|||
|
||||
include('/ipc/chromium/chromium-config.mozbuild')
|
||||
|
||||
EXPORTS += [
|
||||
'nsIconURI.h',
|
||||
]
|
||||
|
||||
platform = None
|
||||
|
||||
if 'gtk' in CONFIG['MOZ_WIDGET_TOOLKIT']:
|
||||
|
|
|
@ -54,15 +54,6 @@ nsIconProtocolHandler::GetProtocolFlags(uint32_t* result) {
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsIconProtocolHandler::NewURI(const nsACString& aSpec,
|
||||
const char* aOriginCharset, // ignored
|
||||
nsIURI* aBaseURI, nsIURI** result) {
|
||||
return NS_MutateURI(new nsMozIconURI::Mutator())
|
||||
.SetSpec(aSpec)
|
||||
.Finalize(result);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsIconProtocolHandler::NewChannel(nsIURI* url, nsILoadInfo* aLoadInfo,
|
||||
nsIChannel** result) {
|
||||
|
|
|
@ -26,6 +26,11 @@ DIRS += [
|
|||
'/mozglue',
|
||||
]
|
||||
|
||||
if CONFIG['JS_BUILD_BINAST']:
|
||||
DIRS += [
|
||||
'/modules/brotli',
|
||||
]
|
||||
|
||||
if CONFIG['USE_ICU']:
|
||||
DIRS += [
|
||||
'/config/external/icu',
|
||||
|
|
|
@ -52,6 +52,11 @@ USE_LIBS += [
|
|||
'zlib',
|
||||
]
|
||||
|
||||
if CONFIG['JS_BUILD_BINAST']:
|
||||
USE_LIBS += [
|
||||
'brotli',
|
||||
]
|
||||
|
||||
if CONFIG['OS_ARCH'] not in ('WINNT', 'HP-UX'):
|
||||
OS_LIBS += [
|
||||
'm',
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
|
||||
#include "mozilla/Result.h" // MOZ_TRY*
|
||||
|
||||
#include <string.h> // memcmp
|
||||
#include <string.h> // memcmp, memmove
|
||||
|
||||
#include "frontend/BinAST-macros.h" // BINJS_TRY*, BINJS_MOZ_TRY*
|
||||
#include "vm/JSScript.h" // ScriptSource
|
||||
|
@ -43,6 +43,72 @@ BinASTTokenReaderContext::~BinASTTokenReaderContext() {
|
|||
if (metadata_ && metadataOwned_ == MetadataOwnership::Owned) {
|
||||
UniqueBinASTSourceMetadataPtr ptr(metadata_);
|
||||
}
|
||||
if (decoder_) {
|
||||
BrotliDecoderDestroyInstance(decoder_);
|
||||
}
|
||||
}
|
||||
|
||||
template <>
|
||||
JS::Result<Ok>
|
||||
BinASTTokenReaderContext::readBuf<BinASTTokenReaderContext::Compression::No>(
|
||||
uint8_t* bytes, uint32_t len) {
|
||||
return Base::readBuf(bytes, len);
|
||||
}
|
||||
|
||||
template <>
|
||||
JS::Result<Ok>
|
||||
BinASTTokenReaderContext::readBuf<BinASTTokenReaderContext::Compression::Yes>(
|
||||
uint8_t* bytes, uint32_t len) {
|
||||
while (availableDecodedLength() < len) {
|
||||
if (availableDecodedLength()) {
|
||||
memmove(bytes, decodedBufferBegin(), availableDecodedLength());
|
||||
bytes += availableDecodedLength();
|
||||
len -= availableDecodedLength();
|
||||
}
|
||||
|
||||
if (isEOF()) {
|
||||
return raiseError("Unexpected end of file");
|
||||
}
|
||||
|
||||
// We have exhausted the in-memory buffer. Start from the beginning.
|
||||
decodedBegin_ = 0;
|
||||
|
||||
size_t inSize = stop_ - current_;
|
||||
size_t outSize = DECODED_BUFFER_SIZE;
|
||||
uint8_t* out = decodedBuffer_;
|
||||
|
||||
BrotliDecoderResult result;
|
||||
result = BrotliDecoderDecompressStream(decoder_, &inSize, ¤t_,
|
||||
&outSize, &out,
|
||||
/* total_out = */ nullptr);
|
||||
if (result == BROTLI_DECODER_RESULT_ERROR) {
|
||||
return raiseError("Failed to decompress brotli stream");
|
||||
}
|
||||
|
||||
decodedEnd_ = out - decodedBuffer_;
|
||||
}
|
||||
|
||||
memmove(bytes, decodedBufferBegin(), len);
|
||||
decodedBegin_ += len;
|
||||
return Ok();
|
||||
}
|
||||
|
||||
bool BinASTTokenReaderContext::isEOF() const {
|
||||
return BrotliDecoderIsFinished(decoder_);
|
||||
}
|
||||
|
||||
template <>
|
||||
JS::Result<uint8_t> BinASTTokenReaderContext::readByte<
|
||||
BinASTTokenReaderContext::Compression::No>() {
|
||||
return Base::readByte();
|
||||
}
|
||||
|
||||
template <>
|
||||
JS::Result<uint8_t> BinASTTokenReaderContext::readByte<
|
||||
BinASTTokenReaderContext::Compression::Yes>() {
|
||||
uint8_t buf;
|
||||
MOZ_TRY(readBuf<Compression::Yes>(&buf, 1));
|
||||
return buf;
|
||||
}
|
||||
|
||||
BinASTSourceMetadata* BinASTTokenReaderContext::takeMetadata() {
|
||||
|
@ -65,13 +131,20 @@ JS::Result<Ok> BinASTTokenReaderContext::readHeader() {
|
|||
|
||||
// Read global headers.
|
||||
MOZ_TRY(readConst(CX_MAGIC_HEADER));
|
||||
BINJS_MOZ_TRY_DECL(version, readVarU32());
|
||||
BINJS_MOZ_TRY_DECL(version, readVarU32<Compression::No>());
|
||||
|
||||
if (version != MAGIC_FORMAT_VERSION) {
|
||||
return raiseError("Format version not implemented");
|
||||
}
|
||||
|
||||
// TODO: handle `LinkToSharedDictionary` and remaining things here.
|
||||
decoder_ = BrotliDecoderCreateInstance(/* alloc_func = */ nullptr,
|
||||
/* free_func = */ nullptr,
|
||||
/* opaque = */ nullptr);
|
||||
if (!decoder_) {
|
||||
return raiseError("Failed to create brotli decoder");
|
||||
}
|
||||
|
||||
// TODO: handle strings and models here.
|
||||
|
||||
return raiseError("Not Yet Implemented");
|
||||
}
|
||||
|
@ -169,13 +242,14 @@ JS::Result<Ok> BinASTTokenReaderContext::AutoList::done() {
|
|||
//
|
||||
// Encoded as variable length number.
|
||||
|
||||
MOZ_MUST_USE JS::Result<uint32_t> BinASTTokenReaderContext::readVarU32() {
|
||||
template <BinASTTokenReaderContext::Compression compression>
|
||||
JS::Result<uint32_t> BinASTTokenReaderContext::readVarU32() {
|
||||
uint32_t result = 0;
|
||||
uint32_t shift = 0;
|
||||
while (true) {
|
||||
MOZ_ASSERT(shift < 32);
|
||||
uint32_t byte;
|
||||
MOZ_TRY_VAR(byte, readByte());
|
||||
MOZ_TRY_VAR(byte, readByte<compression>());
|
||||
|
||||
const uint32_t newResult = result | (byte & 0x7f) << shift;
|
||||
if (newResult < result) {
|
||||
|
@ -195,6 +269,10 @@ MOZ_MUST_USE JS::Result<uint32_t> BinASTTokenReaderContext::readVarU32() {
|
|||
}
|
||||
}
|
||||
|
||||
JS::Result<uint32_t> BinASTTokenReaderContext::readUnsignedLong(const Context&) {
|
||||
return readVarU32<Compression::Yes>();
|
||||
}
|
||||
|
||||
BinASTTokenReaderContext::AutoTaggedTuple::AutoTaggedTuple(
|
||||
BinASTTokenReaderContext& reader)
|
||||
: AutoBase(reader) {}
|
||||
|
|
|
@ -12,6 +12,8 @@
|
|||
|
||||
#include "mozilla/Maybe.h" // mozilla::Maybe
|
||||
|
||||
#include <brotli/decode.h> // BrotliDecoderState
|
||||
|
||||
#include <stddef.h> // size_t
|
||||
#include <stdint.h> // uint8_t, uint32_t
|
||||
|
||||
|
@ -48,6 +50,8 @@ class ErrorReporter;
|
|||
* - the reader does not support lookahead or pushback.
|
||||
*/
|
||||
class MOZ_STACK_CLASS BinASTTokenReaderContext : public BinASTTokenReaderBase {
|
||||
using Base = BinASTTokenReaderBase;
|
||||
|
||||
public:
|
||||
class AutoList;
|
||||
class AutoTaggedTuple;
|
||||
|
@ -82,6 +86,51 @@ class MOZ_STACK_CLASS BinASTTokenReaderContext : public BinASTTokenReaderBase {
|
|||
|
||||
~BinASTTokenReaderContext();
|
||||
|
||||
private:
|
||||
// {readByte, readBuf, readVarU32} are implemented both for uncompressed
|
||||
// stream and brotli-compressed stream.
|
||||
//
|
||||
// Uncompressed variant is for reading the magic header, and compressed
|
||||
// variant is for reading the remaining part.
|
||||
//
|
||||
// Once compressed variant is called, the underlying uncompressed stream is
|
||||
// buffered and uncompressed variant cannot be called.
|
||||
enum class Compression { No, Yes };
|
||||
|
||||
// Buffer that holds already brotli-decoded but not yet used data.
|
||||
// decodedBuffer[decodedBegin, decodedEnd) holds the data.
|
||||
static const size_t DECODED_BUFFER_SIZE = 128;
|
||||
uint8_t decodedBuffer_[DECODED_BUFFER_SIZE];
|
||||
size_t decodedBegin_ = 0;
|
||||
size_t decodedEnd_ = 0;
|
||||
|
||||
// The number of already decoded bytes.
|
||||
size_t availableDecodedLength() const { return decodedEnd_ - decodedBegin_; }
|
||||
|
||||
// The beginning of decoded buffer.
|
||||
const uint8_t* decodedBufferBegin() const {
|
||||
return decodedBuffer_ + decodedBegin_;
|
||||
}
|
||||
|
||||
// Returns true if the brotli stream finished.
|
||||
bool isEOF() const;
|
||||
|
||||
/**
|
||||
* Read a single byte.
|
||||
*/
|
||||
template <Compression compression>
|
||||
MOZ_MUST_USE JS::Result<uint8_t> readByte();
|
||||
|
||||
/**
|
||||
* Read several bytes.
|
||||
*
|
||||
* If there is not enough data, or if the tokenizer has previously been
|
||||
* poisoned, return an error.
|
||||
*/
|
||||
template <Compression compression>
|
||||
MOZ_MUST_USE JS::Result<Ok> readBuf(uint8_t* bytes, uint32_t len);
|
||||
|
||||
public:
|
||||
/**
|
||||
* Read the header of the file.
|
||||
*/
|
||||
|
@ -196,14 +245,13 @@ class MOZ_STACK_CLASS BinASTTokenReaderContext : public BinASTTokenReaderBase {
|
|||
/**
|
||||
* Read a single unsigned long.
|
||||
*/
|
||||
MOZ_MUST_USE JS::Result<uint32_t> readUnsignedLong(const Context&) {
|
||||
return readVarU32();
|
||||
}
|
||||
MOZ_MUST_USE JS::Result<uint32_t> readUnsignedLong(const Context&);
|
||||
|
||||
private:
|
||||
/**
|
||||
* Read a single uint32_t.
|
||||
*/
|
||||
template <Compression compression>
|
||||
MOZ_MUST_USE JS::Result<uint32_t> readVarU32();
|
||||
|
||||
private:
|
||||
|
@ -219,6 +267,8 @@ class MOZ_STACK_CLASS BinASTTokenReaderContext : public BinASTTokenReaderBase {
|
|||
|
||||
const uint8_t* posBeforeTree_;
|
||||
|
||||
BrotliDecoderState* decoder_ = nullptr;
|
||||
|
||||
public:
|
||||
BinASTTokenReaderContext(const BinASTTokenReaderContext&) = delete;
|
||||
BinASTTokenReaderContext(BinASTTokenReaderContext&&) = delete;
|
||||
|
|
|
@ -100,6 +100,7 @@ case $cmd in
|
|||
|
||||
${MKDIR} -p ${tgtpath}/modules
|
||||
cp -pPR \
|
||||
${TOPSRCDIR}/modules/brotli \
|
||||
${TOPSRCDIR}/modules/fdlibm \
|
||||
${TOPSRCDIR}/modules/zlib \
|
||||
${tgtpath}/modules/
|
||||
|
|
|
@ -43,7 +43,9 @@ function run_test() {
|
|||
// try on a new object using the resolved URL
|
||||
var res = Cc["@mozilla.org/network/protocol;1?name=resource"]
|
||||
.getService(Ci.nsIResProtocolHandler);
|
||||
var resURI = res.newURI("resource://gre/modules/XPCOMUtils.jsm");
|
||||
var resURI = Cc["@mozilla.org/network/io-service;1"]
|
||||
.getService(Ci.nsIIOService)
|
||||
.newURI("resource://gre/modules/XPCOMUtils.jsm");
|
||||
dump("resURI: " + resURI + "\n");
|
||||
var filePath = res.resolveURI(resURI);
|
||||
var scope3 = {};
|
||||
|
|
|
@ -61,6 +61,9 @@ typedef void* SockOptArg;
|
|||
#endif // WEBRTC_POSIX
|
||||
|
||||
#if defined(WEBRTC_POSIX) && !defined(WEBRTC_MAC) && !defined(WEBRTC_BSD) && !defined(__native_client__)
|
||||
#if defined(WEBRTC_LINUX)
|
||||
#include <linux/sockios.h>
|
||||
#endif
|
||||
|
||||
int64_t GetSocketRecvTimestamp(int socket) {
|
||||
struct timeval tv_ioctl;
|
||||
|
|
|
@ -88,16 +88,6 @@ nsJARProtocolHandler::GetProtocolFlags(uint32_t* result) {
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsJARProtocolHandler::NewURI(const nsACString& aSpec, const char* aCharset,
|
||||
nsIURI* aBaseURI, nsIURI** result) {
|
||||
nsCOMPtr<nsIURI> base(aBaseURI);
|
||||
return NS_MutateURI(new nsJARURI::Mutator())
|
||||
.Apply(NS_MutatorMethod(&nsIJARURIMutator::SetSpecBaseCharset,
|
||||
nsCString(aSpec), base, aCharset))
|
||||
.Finalize(result);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsJARProtocolHandler::NewChannel(nsIURI* uri, nsILoadInfo* aLoadInfo,
|
||||
nsIChannel** result) {
|
||||
|
|
|
@ -5101,7 +5101,6 @@ pref("gfx.apitrace.enabled",false);
|
|||
#ifdef MOZ_X11
|
||||
#ifdef MOZ_WIDGET_GTK
|
||||
pref("gfx.xrender.enabled",false);
|
||||
pref("widget.chrome.allow-gtk-dark-theme", false);
|
||||
pref("widget.content.allow-gtk-dark-theme", false);
|
||||
#endif
|
||||
#endif
|
||||
|
|
|
@ -62,6 +62,10 @@
|
|||
#include "nsContentUtils.h"
|
||||
#include "nsExceptionHandler.h"
|
||||
|
||||
#ifdef MOZ_WIDGET_GTK
|
||||
# include "nsGIOProtocolHandler.h"
|
||||
#endif
|
||||
|
||||
namespace mozilla {
|
||||
namespace net {
|
||||
|
||||
|
@ -708,24 +712,14 @@ nsIOService::GetProtocolHandler(const char* scheme,
|
|||
}
|
||||
|
||||
#ifdef MOZ_WIDGET_GTK
|
||||
// check to see whether GVFS can handle this URI scheme. if it can
|
||||
// create a nsIURI for the "scheme:", then we assume it has support for
|
||||
// the requested protocol. otherwise, we failover to using the default
|
||||
// protocol handler.
|
||||
// check to see whether GVFS can handle this URI scheme. otherwise, we
|
||||
// failover to using the default protocol handler.
|
||||
|
||||
rv =
|
||||
CallGetService(NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX "moz-gio", result);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
nsAutoCString spec(scheme);
|
||||
spec.Append(':');
|
||||
|
||||
nsCOMPtr<nsIURI> uri;
|
||||
rv = (*result)->NewURI(spec, nullptr, nullptr, getter_AddRefs(uri));
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_RELEASE(*result);
|
||||
RefPtr<nsGIOProtocolHandler> gioHandler =
|
||||
nsGIOProtocolHandler::GetSingleton();
|
||||
if (gioHandler->IsSupportedProtocol(nsCString(scheme))) {
|
||||
gioHandler.forget(result);
|
||||
return NS_OK;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
@ -802,34 +796,7 @@ class AutoIncrement {
|
|||
|
||||
nsresult nsIOService::NewURI(const nsACString& aSpec, const char* aCharset,
|
||||
nsIURI* aBaseURI, nsIURI** result) {
|
||||
NS_ASSERTION(NS_IsMainThread(), "wrong thread");
|
||||
|
||||
static uint32_t recursionCount = 0;
|
||||
if (recursionCount >= MAX_RECURSION_COUNT) return NS_ERROR_MALFORMED_URI;
|
||||
AutoIncrement inc(&recursionCount);
|
||||
|
||||
nsAutoCString scheme;
|
||||
nsresult rv = ExtractScheme(aSpec, scheme);
|
||||
if (NS_FAILED(rv)) {
|
||||
// then aSpec is relative
|
||||
if (!aBaseURI) return NS_ERROR_MALFORMED_URI;
|
||||
|
||||
if (!aSpec.IsEmpty() && aSpec[0] == '#') {
|
||||
// Looks like a reference instead of a fully-specified URI.
|
||||
// --> initialize |uri| as a clone of |aBaseURI|, with ref appended.
|
||||
return NS_GetURIWithNewRef(aBaseURI, aSpec, result);
|
||||
}
|
||||
|
||||
rv = aBaseURI->GetScheme(scheme);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
}
|
||||
|
||||
// now get the handler for this scheme
|
||||
nsCOMPtr<nsIProtocolHandler> handler;
|
||||
rv = GetProtocolHandler(scheme.get(), getter_AddRefs(handler));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
return handler->NewURI(aSpec, aCharset, aBaseURI, result);
|
||||
return NS_NewURI(result, aSpec, aCharset, aBaseURI, nullptr);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
|
|
@ -80,35 +80,6 @@ interface nsIProtocolHandler : nsISupports
|
|||
}
|
||||
%}
|
||||
|
||||
/**
|
||||
* Makes a URI object that is suitable for loading by this protocol,
|
||||
* where the URI string is given as an UTF-8 string. The caller may
|
||||
* provide the charset from which the URI string originated, so that
|
||||
* the URI string can be translated back to that charset (if necessary)
|
||||
* before communicating with, for example, the origin server of the URI
|
||||
* string. (Many servers do not support UTF-8 IRIs at the present time,
|
||||
* so we must be careful about tracking the native charset of the origin
|
||||
* server.)
|
||||
*
|
||||
* @param aSpec - the URI string in UTF-8 encoding. depending
|
||||
* on the protocol implementation, unicode character
|
||||
* sequences may or may not be %xx escaped.
|
||||
* @param aOriginCharset - the charset of the document from which this URI
|
||||
* string originated. this corresponds to the
|
||||
* charset that should be used when communicating
|
||||
* this URI to an origin server, for example. if
|
||||
* null, then UTF-8 encoding is assumed (i.e.,
|
||||
* no charset transformation from aSpec).
|
||||
* @param aBaseURI - if null, aSpec must specify an absolute URI.
|
||||
* otherwise, aSpec may be resolved relative
|
||||
* to aBaseURI, depending on the protocol.
|
||||
* If the protocol has no concept of relative
|
||||
* URI aBaseURI will simply be ignored.
|
||||
*/
|
||||
nsIURI newURI(in AUTF8String aSpec,
|
||||
[optional] in string aOriginCharset,
|
||||
[optional] in nsIURI aBaseURI);
|
||||
|
||||
/**
|
||||
* Constructs a new channel from the given URI for this protocol handler and
|
||||
* sets the loadInfo for the constructed channel.
|
||||
|
|
|
@ -97,7 +97,12 @@
|
|||
#include "mozilla/dom/BlobURLProtocolHandler.h"
|
||||
#include "nsStreamUtils.h"
|
||||
#include "nsSocketTransportService2.h"
|
||||
|
||||
#include "nsViewSourceHandler.h"
|
||||
#include "nsJARURI.h"
|
||||
#include "nsIconURI.h"
|
||||
#include "nsAboutProtocolHandler.h"
|
||||
#include "nsResProtocolHandler.h"
|
||||
#include "mozilla/net/ExtensionProtocolHandler.h"
|
||||
#include <limits>
|
||||
|
||||
using namespace mozilla;
|
||||
|
@ -1616,19 +1621,6 @@ nsresult NS_ReadInputStreamToString(nsIInputStream* aInputStream,
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult NS_NewURI(
|
||||
nsIURI** result, const nsACString& spec,
|
||||
const char* charset /* = nullptr */, nsIURI* baseURI /* = nullptr */,
|
||||
nsIIOService*
|
||||
ioService /* = nullptr */) // pass in nsIIOService to optimize callers
|
||||
{
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIIOService> grip;
|
||||
rv = net_EnsureIOService(&ioService, grip);
|
||||
if (ioService) rv = ioService->NewURI(spec, charset, baseURI, result);
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsresult NS_NewURI(
|
||||
nsIURI** result, const nsACString& spec, NotNull<const Encoding*> encoding,
|
||||
nsIURI* baseURI /* = nullptr */,
|
||||
|
@ -1708,10 +1700,10 @@ class TlsAutoIncrement {
|
|||
T& mVar;
|
||||
};
|
||||
|
||||
nsresult NS_NewURIOnAnyThread(nsIURI** aURI, const nsACString& aSpec,
|
||||
const char* aCharset /* = nullptr */,
|
||||
nsIURI* aBaseURI /* = nullptr */,
|
||||
nsIIOService* aIOService /* = nullptr */) {
|
||||
nsresult NS_NewURI(nsIURI** aURI, const nsACString& aSpec,
|
||||
const char* aCharset /* = nullptr */,
|
||||
nsIURI* aBaseURI /* = nullptr */,
|
||||
nsIIOService* aIOService /* = nullptr */) {
|
||||
TlsAutoIncrement<decltype(gTlsURLRecursionCount)> inc(gTlsURLRecursionCount);
|
||||
if (inc.value() >= MAX_RECURSION_COUNT) {
|
||||
return NS_ERROR_MALFORMED_URI;
|
||||
|
@ -1746,6 +1738,9 @@ nsresult NS_NewURIOnAnyThread(nsIURI** aURI, const nsACString& aSpec,
|
|||
if (scheme.EqualsLiteral("ftp")) {
|
||||
return NewStandardURI(aSpec, aCharset, aBaseURI, 21, aURI);
|
||||
}
|
||||
if (scheme.EqualsLiteral("ssh")) {
|
||||
return NewStandardURI(aSpec, aCharset, aBaseURI, 22, aURI);
|
||||
}
|
||||
|
||||
if (scheme.EqualsLiteral("file")) {
|
||||
nsAutoCString buf(aSpec);
|
||||
|
@ -1793,13 +1788,99 @@ nsresult NS_NewURIOnAnyThread(nsIURI** aURI, const nsACString& aSpec,
|
|||
aURI);
|
||||
}
|
||||
|
||||
if (NS_IsMainThread()) {
|
||||
// XXX (valentin): this fallback should be removed once we get rid of
|
||||
// nsIProtocolHandler.newURI
|
||||
return NS_NewURI(aURI, aSpec, aCharset, aBaseURI, aIOService);
|
||||
if (scheme.EqualsLiteral("view-source")) {
|
||||
return nsViewSourceHandler::CreateNewURI(aSpec, aCharset, aBaseURI, aURI);
|
||||
}
|
||||
|
||||
return NS_ERROR_UNKNOWN_PROTOCOL;
|
||||
if (scheme.EqualsLiteral("resource")) {
|
||||
RefPtr<nsResProtocolHandler> handler = nsResProtocolHandler::GetSingleton();
|
||||
if (!handler) {
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
return handler->NewURI(aSpec, aCharset, aBaseURI, aURI);
|
||||
}
|
||||
|
||||
if (scheme.EqualsLiteral("indexeddb")) {
|
||||
nsCOMPtr<nsIURI> base(aBaseURI);
|
||||
return NS_MutateURI(new nsStandardURL::Mutator())
|
||||
.Apply(NS_MutatorMethod(&nsIStandardURLMutator::Init,
|
||||
nsIStandardURL::URLTYPE_AUTHORITY, 0,
|
||||
nsCString(aSpec), aCharset, base, nullptr))
|
||||
.Finalize(aURI);
|
||||
}
|
||||
|
||||
if (scheme.EqualsLiteral("moz-extension")) {
|
||||
if (!NS_IsMainThread()) {
|
||||
return NS_ERROR_UNKNOWN_PROTOCOL;
|
||||
}
|
||||
// TODO: must be thread safe
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
RefPtr<mozilla::net::ExtensionProtocolHandler> handler =
|
||||
mozilla::net::ExtensionProtocolHandler::GetSingleton();
|
||||
if (!handler) {
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
return handler->NewURI(aSpec, aCharset, aBaseURI, aURI);
|
||||
}
|
||||
|
||||
if (scheme.EqualsLiteral("about")) {
|
||||
return nsAboutProtocolHandler::CreateNewURI(aSpec, aCharset, aBaseURI,
|
||||
aURI);
|
||||
}
|
||||
|
||||
if (scheme.EqualsLiteral("jar")) {
|
||||
nsCOMPtr<nsIURI> base(aBaseURI);
|
||||
return NS_MutateURI(new nsJARURI::Mutator())
|
||||
.Apply(NS_MutatorMethod(&nsIJARURIMutator::SetSpecBaseCharset,
|
||||
nsCString(aSpec), base, aCharset))
|
||||
.Finalize(aURI);
|
||||
}
|
||||
|
||||
if (scheme.EqualsLiteral("moz-icon")) {
|
||||
return NS_MutateURI(new nsMozIconURI::Mutator())
|
||||
.SetSpec(aSpec)
|
||||
.Finalize(aURI);
|
||||
}
|
||||
|
||||
#ifdef MOZ_WIDGET_GTK
|
||||
if (scheme.EqualsLiteral("smb") || scheme.EqualsLiteral("sftp")) {
|
||||
nsCOMPtr<nsIURI> base(aBaseURI);
|
||||
return NS_MutateURI(new nsStandardURL::Mutator())
|
||||
.Apply(NS_MutatorMethod(&nsIStandardURLMutator::Init,
|
||||
nsIStandardURL::URLTYPE_STANDARD, -1,
|
||||
nsCString(aSpec), aCharset, base, nullptr))
|
||||
.Finalize(aURI);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (scheme.EqualsLiteral("android")) {
|
||||
nsCOMPtr<nsIURI> base(aBaseURI);
|
||||
return NS_MutateURI(NS_STANDARDURLMUTATOR_CONTRACTID)
|
||||
.Apply(NS_MutatorMethod(&nsIStandardURLMutator::Init,
|
||||
nsIStandardURL::URLTYPE_STANDARD, -1,
|
||||
nsCString(aSpec), aCharset, base, nullptr))
|
||||
.Finalize(aURI);
|
||||
}
|
||||
|
||||
if (aBaseURI) {
|
||||
nsAutoCString newSpec;
|
||||
rv = aBaseURI->Resolve(aSpec, newSpec);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsAutoCString newScheme;
|
||||
rv = net_ExtractURLScheme(newSpec, newScheme);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
// The scheme shouldn't really change at this point.
|
||||
MOZ_DIAGNOSTIC_ASSERT(newScheme == scheme);
|
||||
}
|
||||
|
||||
return NS_MutateURI(new nsSimpleURI::Mutator())
|
||||
.SetSpec(newSpec)
|
||||
.Finalize(aURI);
|
||||
}
|
||||
|
||||
// Falls back to external protocol handler.
|
||||
return NS_MutateURI(new nsSimpleURI::Mutator()).SetSpec(aSpec).Finalize(aURI);
|
||||
}
|
||||
|
||||
nsresult NS_GetSanitizedURIStringFromURI(nsIURI* aUri,
|
||||
|
|
|
@ -101,19 +101,6 @@ nsresult NS_NewURI(nsIURI** result, const char* spec, nsIURI* baseURI = nullptr,
|
|||
nsIIOService* ioService =
|
||||
nullptr); // pass in nsIIOService to optimize callers
|
||||
|
||||
// This function attempts to create an nsIURI on any thread. This implies we
|
||||
// can't instantiate a protcol handler, since protocol handers may have a JS
|
||||
// implementation so they can't work off-main-thread.
|
||||
// When called off the main thread, if the nsIURI can't be created without
|
||||
// instantiating protocol handlers, the method will return
|
||||
// NS_ERROR_UNKNOWN_PROTOCOL. The caller may retry on the main thread.
|
||||
// When called on the main thread, this function will fall back on calling
|
||||
// nsIProtocolHandler.newURI
|
||||
nsresult NS_NewURIOnAnyThread(nsIURI** aResult, const nsACString& aSpec,
|
||||
const char* aCharset = nullptr,
|
||||
nsIURI* aBaseURI = nullptr,
|
||||
nsIIOService* aIOService = nullptr);
|
||||
|
||||
nsresult NS_NewFileURI(
|
||||
nsIURI** result, nsIFile* spec,
|
||||
nsIIOService* ioService =
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#include "mozilla/MemoryReporting.h"
|
||||
#include "mozilla/ipc/URIUtils.h"
|
||||
#include "nsIURIMutator.h"
|
||||
#include "mozilla/net/MozURL.h"
|
||||
|
||||
using namespace mozilla::ipc;
|
||||
|
||||
|
@ -581,7 +582,41 @@ nsresult nsSimpleURI::CloneInternal(
|
|||
|
||||
NS_IMETHODIMP
|
||||
nsSimpleURI::Resolve(const nsACString& relativePath, nsACString& result) {
|
||||
result = relativePath;
|
||||
nsAutoCString scheme;
|
||||
nsresult rv = net_ExtractURLScheme(relativePath, scheme);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
result = relativePath;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsAutoCString spec;
|
||||
rv = GetAsciiSpec(spec);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
// If getting the spec fails for some reason, preserve behaviour and just
|
||||
// return the relative path.
|
||||
result = relativePath;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
RefPtr<MozURL> url;
|
||||
rv = MozURL::Init(getter_AddRefs(url), spec);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
// If parsing the current url fails, we revert to the previous behaviour
|
||||
// and just return the relative path.
|
||||
result = relativePath;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
RefPtr<MozURL> url2;
|
||||
rv = MozURL::Init(getter_AddRefs(url2), relativePath, url);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
// If parsing the relative url fails, we revert to the previous behaviour
|
||||
// and just return the relative path.
|
||||
result = relativePath;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
result = url2->Spec();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -316,7 +316,7 @@ Classes = [
|
|||
'singleton': True,
|
||||
'type': 'nsResProtocolHandler',
|
||||
'headers': ['/netwerk/protocol/res/nsResProtocolHandler.h'],
|
||||
'init_method': 'Init',
|
||||
'constructor': 'nsResProtocolHandler::GetSingleton',
|
||||
},
|
||||
{
|
||||
'cid': '{9c7ec5d1-23f9-11d5-aea8-8fcc0793e97f}',
|
||||
|
|
|
@ -11,6 +11,7 @@ XPIDL_SOURCES += [
|
|||
XPIDL_MODULE = 'necko_about'
|
||||
|
||||
EXPORTS += [
|
||||
'nsAboutProtocolHandler.h',
|
||||
'nsAboutProtocolUtils.h',
|
||||
]
|
||||
|
||||
|
|
|
@ -36,15 +36,32 @@ static bool IsSafeForUntrustedContent(nsIAboutModule* aModule, nsIURI* aURI) {
|
|||
return (flags & nsIAboutModule::URI_SAFE_FOR_UNTRUSTED_CONTENT) != 0;
|
||||
}
|
||||
|
||||
static bool IsSafeToLinkForUntrustedContent(nsIAboutModule* aModule,
|
||||
nsIURI* aURI) {
|
||||
uint32_t flags;
|
||||
nsresult rv = aModule->GetURIFlags(aURI, &flags);
|
||||
NS_ENSURE_SUCCESS(rv, false);
|
||||
static bool IsSafeToLinkForUntrustedContent(nsIURI* aURI) {
|
||||
nsAutoCString path;
|
||||
aURI->GetPathQueryRef(path);
|
||||
|
||||
return (flags & nsIAboutModule::URI_SAFE_FOR_UNTRUSTED_CONTENT) &&
|
||||
(flags & nsIAboutModule::MAKE_LINKABLE);
|
||||
int32_t f = path.FindChar('#');
|
||||
if (f >= 0) {
|
||||
path.SetLength(f);
|
||||
}
|
||||
|
||||
f = path.FindChar('?');
|
||||
if (f >= 0) {
|
||||
path.SetLength(f);
|
||||
}
|
||||
|
||||
ToLowerCase(path);
|
||||
|
||||
// The about modules for these URL types have the
|
||||
// URI_SAFE_FOR_UNTRUSTED_CONTENT and MAKE_LINKABLE flags set.
|
||||
if (path.EqualsLiteral("blank") || path.EqualsLiteral("license") ||
|
||||
path.EqualsLiteral("logo") || path.EqualsLiteral("srcdoc")) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
NS_IMPL_ISUPPORTS(nsAboutProtocolHandler, nsIProtocolHandler,
|
||||
|
@ -104,11 +121,12 @@ nsAboutProtocolHandler::GetFlagsForURI(nsIURI* aURI, uint32_t* aFlags) {
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsAboutProtocolHandler::NewURI(const nsACString& aSpec,
|
||||
const char* aCharset, // ignore charset info
|
||||
nsIURI* aBaseURI, nsIURI** result) {
|
||||
*result = nullptr;
|
||||
// static
|
||||
nsresult nsAboutProtocolHandler::CreateNewURI(const nsACString& aSpec,
|
||||
const char* aCharset,
|
||||
nsIURI* aBaseURI,
|
||||
nsIURI** aResult) {
|
||||
*aResult = nullptr;
|
||||
nsresult rv;
|
||||
|
||||
// Use a simple URI to parse out some stuff first
|
||||
|
@ -119,18 +137,7 @@ nsAboutProtocolHandler::NewURI(const nsACString& aSpec,
|
|||
return rv;
|
||||
}
|
||||
|
||||
// Unfortunately, people create random about: URIs that don't correspond to
|
||||
// about: modules... Since those URIs will never open a channel, might as
|
||||
// well consider them unsafe for better perf, and just in case.
|
||||
bool isSafe = false;
|
||||
|
||||
nsCOMPtr<nsIAboutModule> aboutMod;
|
||||
rv = NS_GetAboutModule(url, getter_AddRefs(aboutMod));
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
isSafe = IsSafeToLinkForUntrustedContent(aboutMod, url);
|
||||
}
|
||||
|
||||
if (isSafe) {
|
||||
if (IsSafeToLinkForUntrustedContent(url)) {
|
||||
// We need to indicate that this baby is safe. Use an inner URI that
|
||||
// no one but the security manager will see. Make sure to preserve our
|
||||
// path, in case someone decides to hardcode checks for particular
|
||||
|
@ -154,7 +161,7 @@ nsAboutProtocolHandler::NewURI(const nsACString& aSpec,
|
|||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
url.swap(*result);
|
||||
url.swap(*aResult);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -294,19 +301,6 @@ nsSafeAboutProtocolHandler::GetProtocolFlags(uint32_t* result) {
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSafeAboutProtocolHandler::NewURI(const nsACString& aSpec,
|
||||
const char* aCharset, // ignore charset info
|
||||
nsIURI* aBaseURI, nsIURI** result) {
|
||||
nsresult rv =
|
||||
NS_MutateURI(new nsSimpleURI::Mutator()).SetSpec(aSpec).Finalize(result);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSafeAboutProtocolHandler::NewChannel(nsIURI* uri, nsILoadInfo* aLoadInfo,
|
||||
nsIChannel** result) {
|
||||
|
|
|
@ -30,6 +30,9 @@ class nsAboutProtocolHandler : public nsIProtocolHandlerWithDynamicFlags,
|
|||
// nsAboutProtocolHandler methods:
|
||||
nsAboutProtocolHandler() = default;
|
||||
|
||||
static nsresult CreateNewURI(const nsACString& aSpec, const char* aCharset,
|
||||
nsIURI* aBaseURI, nsIURI** result);
|
||||
|
||||
private:
|
||||
virtual ~nsAboutProtocolHandler() = default;
|
||||
};
|
||||
|
|
|
@ -68,6 +68,9 @@ interface nsIAboutModule : nsISupports
|
|||
/**
|
||||
* A flag that indicates that this URI should be linkable from content.
|
||||
* Ignored unless URI_SAFE_FOR_UNTRUSTED_CONTENT is also specified.
|
||||
*
|
||||
* When adding a new about module with this flag make sure to also update
|
||||
* IsSafeToLinkForUntrustedContent() in nsAboutProtocolHandler.cpp
|
||||
*/
|
||||
const unsigned long MAKE_LINKABLE = (1 << 7);
|
||||
|
||||
|
|
|
@ -47,13 +47,6 @@ nsDataHandler::GetProtocolFlags(uint32_t* result) {
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDataHandler::NewURI(const nsACString& aSpec,
|
||||
const char* aCharset, // ignore charset info
|
||||
nsIURI* aBaseURI, nsIURI** result) {
|
||||
return nsDataHandler::CreateNewURI(aSpec, aCharset, aBaseURI, result);
|
||||
}
|
||||
|
||||
/* static */ nsresult nsDataHandler::CreateNewURI(const nsACString& aSpec,
|
||||
const char* aCharset,
|
||||
nsIURI* aBaseURI,
|
||||
|
|
|
@ -143,26 +143,6 @@ nsFileProtocolHandler::GetProtocolFlags(uint32_t* result) {
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFileProtocolHandler::NewURI(const nsACString& spec, const char* charset,
|
||||
nsIURI* aBaseURI, nsIURI** result) {
|
||||
nsAutoCString buf(spec);
|
||||
#if defined(XP_WIN)
|
||||
buf.Truncate();
|
||||
if (!net_NormalizeFileURL(spec, buf)) {
|
||||
buf = spec;
|
||||
}
|
||||
#endif
|
||||
|
||||
nsCOMPtr<nsIURI> base(aBaseURI);
|
||||
return NS_MutateURI(new nsStandardURL::Mutator())
|
||||
.Apply(NS_MutatorMethod(&nsIFileURLMutator::MarkFileURL))
|
||||
.Apply(NS_MutatorMethod(&nsIStandardURLMutator::Init,
|
||||
nsIStandardURL::URLTYPE_NO_AUTHORITY, -1, buf,
|
||||
charset, base, nullptr))
|
||||
.Finalize(result);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFileProtocolHandler::NewChannel(nsIURI* uri, nsILoadInfo* aLoadInfo,
|
||||
nsIChannel** result) {
|
||||
|
|
|
@ -139,37 +139,6 @@ nsFtpProtocolHandler::GetProtocolFlags(uint32_t* result) {
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFtpProtocolHandler::NewURI(const nsACString& aSpec, const char* aCharset,
|
||||
nsIURI* aBaseURI, nsIURI** result) {
|
||||
if (!mEnabled) {
|
||||
return NS_ERROR_UNKNOWN_PROTOCOL;
|
||||
}
|
||||
nsAutoCString spec(aSpec);
|
||||
spec.Trim(" \t\n\r"); // Match NS_IsAsciiWhitespace instead of HTML5
|
||||
|
||||
char* fwdPtr = spec.BeginWriting();
|
||||
|
||||
// now unescape it... %xx reduced inline to resulting character
|
||||
|
||||
int32_t len = NS_UnescapeURL(fwdPtr);
|
||||
|
||||
// NS_UnescapeURL() modified spec's buffer, truncate to ensure
|
||||
// spec knows its new length.
|
||||
spec.Truncate(len);
|
||||
|
||||
// return an error if we find a NUL, CR, or LF in the path
|
||||
if (spec.FindCharInSet(CRLF) >= 0 || spec.FindChar('\0') >= 0)
|
||||
return NS_ERROR_MALFORMED_URI;
|
||||
|
||||
nsCOMPtr<nsIURI> base(aBaseURI);
|
||||
return NS_MutateURI(NS_STANDARDURLMUTATOR_CONTRACTID)
|
||||
.Apply(NS_MutatorMethod(&nsIStandardURLMutator::Init,
|
||||
nsIStandardURL::URLTYPE_AUTHORITY, 21,
|
||||
nsCString(aSpec), aCharset, base, nullptr))
|
||||
.Finalize(result);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFtpProtocolHandler::NewChannel(nsIURI* url, nsILoadInfo* aLoadInfo,
|
||||
nsIChannel** result) {
|
||||
|
|
|
@ -8,6 +8,9 @@ Classes = [
|
|||
{
|
||||
'cid': '{ee706783-3af8-4d19-9e84-e2ebfe213480}',
|
||||
'contract_ids': ['@mozilla.org/network/protocol;1?name=moz-gio'],
|
||||
'singleton': True,
|
||||
'type': 'nsGIOProtocolHandler',
|
||||
'headers': ['nsGIOProtocolHandler.h'],
|
||||
'constructor': 'nsGIOProtocolHandler::GetSingleton',
|
||||
},
|
||||
]
|
||||
|
|
|
@ -12,6 +12,10 @@ XPCOM_MANIFESTS += [
|
|||
'components.conf',
|
||||
]
|
||||
|
||||
EXPORTS += [
|
||||
'nsGIOProtocolHandler.h',
|
||||
]
|
||||
|
||||
FINAL_LIBRARY = 'xul'
|
||||
|
||||
CXXFLAGS += CONFIG['TK_CFLAGS']
|
||||
|
|
|
@ -7,7 +7,9 @@
|
|||
* This code is based on original Mozilla gnome-vfs extension. It implements
|
||||
* input stream provided by GVFS/GIO.
|
||||
*/
|
||||
#include "nsGIOProtocolHandler.h"
|
||||
#include "mozilla/Components.h"
|
||||
#include "mozilla/ClearOnShutdown.h"
|
||||
#include "mozilla/NullPrincipal.h"
|
||||
#include "nsIPrefService.h"
|
||||
#include "nsIPrefBranch.h"
|
||||
|
@ -827,34 +829,19 @@ static void mount_operation_ask_password(
|
|||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
class nsGIOProtocolHandler final : public nsIProtocolHandler,
|
||||
public nsIObserver {
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIPROTOCOLHANDLER
|
||||
NS_DECL_NSIOBSERVER
|
||||
mozilla::StaticRefPtr<nsGIOProtocolHandler> nsGIOProtocolHandler::sSingleton;
|
||||
|
||||
nsresult Init();
|
||||
|
||||
private:
|
||||
~nsGIOProtocolHandler() {}
|
||||
|
||||
void InitSupportedProtocolsPref(nsIPrefBranch* prefs);
|
||||
bool IsSupportedProtocol(const nsCString& spec);
|
||||
|
||||
nsCString mSupportedProtocols;
|
||||
};
|
||||
already_AddRefed<nsGIOProtocolHandler> nsGIOProtocolHandler::GetSingleton() {
|
||||
if (!sSingleton) {
|
||||
sSingleton = new nsGIOProtocolHandler();
|
||||
sSingleton->Init();
|
||||
ClearOnShutdown(&sSingleton);
|
||||
}
|
||||
return do_AddRef(sSingleton);
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS(nsGIOProtocolHandler, nsIProtocolHandler, nsIObserver)
|
||||
|
||||
NS_IMPL_COMPONENT_FACTORY(nsGIOProtocolHandler) {
|
||||
auto inst = MakeRefPtr<nsGIOProtocolHandler>();
|
||||
if (NS_SUCCEEDED(inst->Init())) {
|
||||
return inst.forget().downcast<nsIProtocolHandler>();
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nsresult nsGIOProtocolHandler::Init() {
|
||||
nsCOMPtr<nsIPrefBranch> prefs = do_GetService(NS_PREFSERVICE_CONTRACTID);
|
||||
if (prefs) {
|
||||
|
@ -925,53 +912,27 @@ nsGIOProtocolHandler::GetProtocolFlags(uint32_t* aProtocolFlags) {
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsGIOProtocolHandler::NewURI(const nsACString& aSpec,
|
||||
const char* aOriginCharset, nsIURI* aBaseURI,
|
||||
nsIURI** aResult) {
|
||||
const nsCString flatSpec(aSpec);
|
||||
LOG(("gio: NewURI [spec=%s]\n", flatSpec.get()));
|
||||
static bool IsValidGIOScheme(const nsACString& aScheme) {
|
||||
// Verify that GIO supports this URI scheme.
|
||||
GVfs* gvfs = g_vfs_get_default();
|
||||
|
||||
if (!aBaseURI) {
|
||||
// XXX Is it good to support all GIO protocols?
|
||||
if (!IsSupportedProtocol(flatSpec)) return NS_ERROR_UNKNOWN_PROTOCOL;
|
||||
|
||||
int32_t colon_location = flatSpec.FindChar(':');
|
||||
if (colon_location <= 0) return NS_ERROR_UNKNOWN_PROTOCOL;
|
||||
|
||||
// Verify that GIO supports this URI scheme.
|
||||
bool uri_scheme_supported = false;
|
||||
|
||||
GVfs* gvfs = g_vfs_get_default();
|
||||
|
||||
if (!gvfs) {
|
||||
g_warning("Cannot get GVfs object.");
|
||||
return NS_ERROR_UNKNOWN_PROTOCOL;
|
||||
}
|
||||
|
||||
const gchar* const* uri_schemes = g_vfs_get_supported_uri_schemes(gvfs);
|
||||
|
||||
while (*uri_schemes != nullptr) {
|
||||
// While flatSpec ends with ':' the uri_scheme does not. Therefore do not
|
||||
// compare last character.
|
||||
if (StringHead(flatSpec, colon_location).Equals(*uri_schemes)) {
|
||||
uri_scheme_supported = true;
|
||||
break;
|
||||
}
|
||||
uri_schemes++;
|
||||
}
|
||||
|
||||
if (!uri_scheme_supported) {
|
||||
return NS_ERROR_UNKNOWN_PROTOCOL;
|
||||
}
|
||||
if (!gvfs) {
|
||||
g_warning("Cannot get GVfs object.");
|
||||
return false;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIURI> base(aBaseURI);
|
||||
return NS_MutateURI(NS_STANDARDURLMUTATOR_CONTRACTID)
|
||||
.Apply(NS_MutatorMethod(&nsIStandardURLMutator::Init,
|
||||
nsIStandardURL::URLTYPE_STANDARD, -1, flatSpec,
|
||||
aOriginCharset, base, nullptr))
|
||||
.Finalize(aResult);
|
||||
const gchar* const* uri_schemes = g_vfs_get_supported_uri_schemes(gvfs);
|
||||
|
||||
while (*uri_schemes != nullptr) {
|
||||
// While flatSpec ends with ':' the uri_scheme does not. Therefore do not
|
||||
// compare last character.
|
||||
if (aScheme.Equals(*uri_schemes)) {
|
||||
return true;
|
||||
}
|
||||
uri_schemes++;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
@ -984,6 +945,20 @@ nsGIOProtocolHandler::NewChannel(nsIURI* aURI, nsILoadInfo* aLoadInfo,
|
|||
rv = aURI->GetSpec(spec);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
if (!IsSupportedProtocol(spec)) {
|
||||
return NS_ERROR_UNKNOWN_PROTOCOL;
|
||||
}
|
||||
|
||||
nsAutoCString scheme;
|
||||
rv = aURI->GetScheme(scheme);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
if (!IsValidGIOScheme(scheme)) {
|
||||
return NS_ERROR_UNKNOWN_PROTOCOL;
|
||||
}
|
||||
|
||||
RefPtr<nsGIOInputStream> stream = new nsGIOInputStream(spec);
|
||||
if (!stream) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
/* 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/. */
|
||||
|
||||
#ifndef nsGIOProtocolHandler_h___
|
||||
#define nsGIOProtocolHandler_h___
|
||||
|
||||
#include "nsIProtocolHandler.h"
|
||||
#include "nsIObserver.h"
|
||||
#include "nsIPrefBranch.h"
|
||||
#include "nsStringFwd.h"
|
||||
|
||||
class nsGIOProtocolHandler final : public nsIProtocolHandler,
|
||||
public nsIObserver {
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIPROTOCOLHANDLER
|
||||
NS_DECL_NSIOBSERVER
|
||||
|
||||
static already_AddRefed<nsGIOProtocolHandler> GetSingleton();
|
||||
bool IsSupportedProtocol(const nsCString& spec);
|
||||
|
||||
private:
|
||||
nsresult Init();
|
||||
~nsGIOProtocolHandler() = default;
|
||||
|
||||
void InitSupportedProtocolsPref(nsIPrefBranch* prefs);
|
||||
|
||||
static mozilla::StaticRefPtr<nsGIOProtocolHandler> sSingleton;
|
||||
nsCString mSupportedProtocols;
|
||||
};
|
||||
|
||||
#endif // nsGIOProtocolHandler_h___
|
|
@ -856,6 +856,10 @@ MOZ_MUST_USE nsresult HttpAsyncAborter<T>::AsyncAbort(nsresult status) {
|
|||
template <class T>
|
||||
inline void HttpAsyncAborter<T>::HandleAsyncAbort() {
|
||||
MOZ_ASSERT(!mCallOnResume, "How did that happen?");
|
||||
nsresult status = mThis->mStatus;
|
||||
MOZ_LOG(gHttpLog, LogLevel::Debug,
|
||||
("HttpAsyncAborter::HandleAsyncAbort [this=%p status=%" PRIx32 "]\n",
|
||||
mThis, static_cast<uint32_t>(status)));
|
||||
|
||||
if (mThis->mSuspendCount) {
|
||||
MOZ_LOG(
|
||||
|
|
|
@ -5240,6 +5240,44 @@ nsresult nsHttpChannel::ReadFromCache(bool alreadyMarkedValid) {
|
|||
|
||||
nsresult rv;
|
||||
|
||||
// notify "http-on-may-change-process" observers
|
||||
gHttpHandler->OnMayChangeProcess(this);
|
||||
|
||||
if (mRedirectContentProcessIdPromise) {
|
||||
PushRedirectAsyncFunc(&nsHttpChannel::ContinueReadFromCache);
|
||||
rv = StartCrossProcessRedirect();
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
return NS_OK;
|
||||
}
|
||||
PopRedirectAsyncFunc(&nsHttpChannel::ContinueReadFromCache);
|
||||
}
|
||||
|
||||
return ContinueReadFromCache(NS_OK);
|
||||
}
|
||||
|
||||
nsresult nsHttpChannel::ContinueReadFromCache(nsresult rv) {
|
||||
LOG(("nsHttpChannel::ContinueReadFromCache [this=%p] spec: %s\n", this,
|
||||
mSpec.get()));
|
||||
|
||||
// The channel may have been cancelled in the meantime, either by the
|
||||
// consumer or the channel classifier. In that case, we need to AsyncAbort
|
||||
// to ensure OnStart/StopRequest are called.
|
||||
// This should only be an error code if the cross-process redirect failed,
|
||||
// and OnRedirectVerifyCallback was called with an error code.
|
||||
if (NS_FAILED(rv)) {
|
||||
// rv can only be an error code if this was a failed cross-process redirect
|
||||
// It shouldn't have happened during a revalidation.
|
||||
MOZ_ASSERT(!mDidReval, "Should not be a 304 response");
|
||||
// Also, this should not be possible.
|
||||
MOZ_ASSERT(!mCachedContentIsPartial, "Unexpected partially cached page?");
|
||||
|
||||
MOZ_ASSERT(!mCachePump);
|
||||
|
||||
CloseCacheEntry(false);
|
||||
DoAsyncAbort(NS_FAILED(mStatus) ? mStatus : rv);
|
||||
return rv;
|
||||
}
|
||||
|
||||
// Keep the conditions below in sync with the conditions in
|
||||
// StartBufferingCachedEntity.
|
||||
|
||||
|
|
|
@ -409,6 +409,7 @@ class nsHttpChannel final : public HttpBaseChannel,
|
|||
int64_t* aContentLength);
|
||||
bool ShouldUpdateOfflineCacheEntry();
|
||||
MOZ_MUST_USE nsresult ReadFromCache(bool alreadyMarkedValid);
|
||||
MOZ_MUST_USE nsresult ContinueReadFromCache(nsresult rv);
|
||||
void CloseCacheEntry(bool doomOnFailure);
|
||||
void CloseOfflineCacheEntry();
|
||||
MOZ_MUST_USE nsresult InitCacheEntry();
|
||||
|
|
|
@ -140,16 +140,6 @@ namespace net {
|
|||
|
||||
LazyLogModule gHttpLog("nsHttp");
|
||||
|
||||
static nsresult NewURI(const nsACString& aSpec, const char* aCharset,
|
||||
nsIURI* aBaseURI, int32_t aDefaultPort, nsIURI** aURI) {
|
||||
nsCOMPtr<nsIURI> base(aBaseURI);
|
||||
return NS_MutateURI(new nsStandardURL::Mutator())
|
||||
.Apply(NS_MutatorMethod(&nsIStandardURLMutator::Init,
|
||||
nsIStandardURL::URLTYPE_AUTHORITY, aDefaultPort,
|
||||
nsCString(aSpec), aCharset, base, nullptr))
|
||||
.Finalize(aURI);
|
||||
}
|
||||
|
||||
#ifdef ANDROID
|
||||
static nsCString GetDeviceModelId() {
|
||||
// Assumed to be running on the main thread
|
||||
|
@ -1990,13 +1980,6 @@ nsHttpHandler::GetProtocolFlags(uint32_t* result) {
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHttpHandler::NewURI(const nsACString& aSpec, const char* aCharset,
|
||||
nsIURI* aBaseURI, nsIURI** aURI) {
|
||||
return mozilla::net::NewURI(aSpec, aCharset, aBaseURI, NS_HTTP_DEFAULT_PORT,
|
||||
aURI);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHttpHandler::NewChannel(nsIURI* uri, nsILoadInfo* aLoadInfo,
|
||||
nsIChannel** result) {
|
||||
|
@ -2537,13 +2520,6 @@ nsHttpsHandler::GetProtocolFlags(uint32_t* aProtocolFlags) {
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHttpsHandler::NewURI(const nsACString& aSpec, const char* aOriginCharset,
|
||||
nsIURI* aBaseURI, nsIURI** _retval) {
|
||||
return mozilla::net::NewURI(aSpec, aOriginCharset, aBaseURI,
|
||||
NS_HTTPS_DEFAULT_PORT, _retval);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHttpsHandler::NewChannel(nsIURI* aURI, nsILoadInfo* aLoadInfo,
|
||||
nsIChannel** _retval) {
|
||||
|
|
|
@ -200,6 +200,7 @@ SubstitutingProtocolHandler::SubstitutingProtocolHandler(const char* aScheme,
|
|||
uint32_t aFlags,
|
||||
bool aEnforceFileOrJar)
|
||||
: mScheme(aScheme),
|
||||
mSubstitutionsLock("SubstitutingProtocolHandler::mSubstitutions"),
|
||||
mSubstitutions(16),
|
||||
mEnforceFileOrJar(aEnforceFileOrJar) {
|
||||
mFlags.emplace(aFlags);
|
||||
|
@ -207,7 +208,10 @@ SubstitutingProtocolHandler::SubstitutingProtocolHandler(const char* aScheme,
|
|||
}
|
||||
|
||||
SubstitutingProtocolHandler::SubstitutingProtocolHandler(const char* aScheme)
|
||||
: mScheme(aScheme), mSubstitutions(16), mEnforceFileOrJar(true) {
|
||||
: mScheme(aScheme),
|
||||
mSubstitutionsLock("SubstitutingProtocolHandler::mSubstitutions"),
|
||||
mSubstitutions(16),
|
||||
mEnforceFileOrJar(true) {
|
||||
ConstructInternal();
|
||||
}
|
||||
|
||||
|
@ -223,6 +227,7 @@ void SubstitutingProtocolHandler::ConstructInternal() {
|
|||
|
||||
nsresult SubstitutingProtocolHandler::CollectSubstitutions(
|
||||
InfallibleTArray<SubstitutionMapping>& aMappings) {
|
||||
AutoReadLock lock(mSubstitutionsLock);
|
||||
for (auto iter = mSubstitutions.ConstIter(); !iter.Done(); iter.Next()) {
|
||||
SubstitutionEntry& entry = iter.Data();
|
||||
nsCOMPtr<nsIURI> uri = entry.baseURI;
|
||||
|
@ -348,22 +353,14 @@ nsresult SubstitutingProtocolHandler::NewURI(const nsACString& aSpec,
|
|||
rv = uri->GetHost(host);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
uint32_t flags;
|
||||
rv = GetSubstitutionFlags(host, &flags);
|
||||
if (NS_FAILED(rv)) {
|
||||
// This protocol has not been registered yet or does not exist,
|
||||
// we can assume we don't expose nsIJARURI
|
||||
uri.forget(aResult);
|
||||
return NS_OK;
|
||||
// "android" is the only root that would return the RESOLVE_JAR_URI flag
|
||||
// see nsResProtocolHandler::GetSubstitutionInternal
|
||||
if (host.EqualsLiteral("android")) {
|
||||
return ResolveJARURI(uri, aResult);
|
||||
}
|
||||
|
||||
if (flags & nsISubstitutingProtocolHandler::RESOLVE_JAR_URI) {
|
||||
rv = ResolveJARURI(uri, aResult);
|
||||
} else {
|
||||
uri.forget(aResult);
|
||||
}
|
||||
|
||||
return rv;
|
||||
uri.forget(aResult);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult SubstitutingProtocolHandler::ResolveJARURI(nsIURL* aURL,
|
||||
|
@ -387,9 +384,9 @@ nsresult SubstitutingProtocolHandler::ResolveJARURI(nsIURL* aURL,
|
|||
if (!jarURI) {
|
||||
// This substitution does not resolve to a jar: URL, so we just
|
||||
// return the plain SubstitutionURL
|
||||
*aResult = aURL;
|
||||
NS_ADDREF(*aResult);
|
||||
return rv;
|
||||
nsCOMPtr<nsIURI> url = aURL;
|
||||
url.forget(aResult);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIJARURI> result = new SubstitutingJARURI(aURL, jarURI);
|
||||
|
@ -456,7 +453,10 @@ nsresult SubstitutingProtocolHandler::SetSubstitutionWithFlags(
|
|||
ToLowerCase(origRoot, root);
|
||||
|
||||
if (!baseURI) {
|
||||
mSubstitutions.Remove(root);
|
||||
{
|
||||
AutoWriteLock lock(mSubstitutionsLock);
|
||||
mSubstitutions.Remove(root);
|
||||
}
|
||||
NotifyObservers(root, baseURI);
|
||||
return SendSubstitution(root, baseURI, flags);
|
||||
}
|
||||
|
@ -474,9 +474,12 @@ nsresult SubstitutingProtocolHandler::SetSubstitutionWithFlags(
|
|||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
|
||||
SubstitutionEntry& entry = mSubstitutions.GetOrInsert(root);
|
||||
entry.baseURI = baseURI;
|
||||
entry.flags = flags;
|
||||
{
|
||||
AutoWriteLock lock(mSubstitutionsLock);
|
||||
SubstitutionEntry& entry = mSubstitutions.GetOrInsert(root);
|
||||
entry.baseURI = baseURI;
|
||||
entry.flags = flags;
|
||||
}
|
||||
NotifyObservers(root, baseURI);
|
||||
return SendSubstitution(root, baseURI, flags);
|
||||
}
|
||||
|
@ -491,9 +494,12 @@ nsresult SubstitutingProtocolHandler::SetSubstitutionWithFlags(
|
|||
mIOService->NewURI(newBase, nullptr, nullptr, getter_AddRefs(newBaseURI));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
SubstitutionEntry& entry = mSubstitutions.GetOrInsert(root);
|
||||
entry.baseURI = newBaseURI;
|
||||
entry.flags = flags;
|
||||
{
|
||||
AutoWriteLock lock(mSubstitutionsLock);
|
||||
SubstitutionEntry& entry = mSubstitutions.GetOrInsert(root);
|
||||
entry.baseURI = newBaseURI;
|
||||
entry.flags = flags;
|
||||
}
|
||||
NotifyObservers(root, baseURI);
|
||||
return SendSubstitution(root, newBaseURI, flags);
|
||||
}
|
||||
|
@ -505,11 +511,14 @@ nsresult SubstitutingProtocolHandler::GetSubstitution(
|
|||
nsAutoCString root;
|
||||
ToLowerCase(origRoot, root);
|
||||
|
||||
SubstitutionEntry entry;
|
||||
if (mSubstitutions.Get(root, &entry)) {
|
||||
nsCOMPtr<nsIURI> baseURI = entry.baseURI;
|
||||
baseURI.forget(result);
|
||||
return NS_OK;
|
||||
{
|
||||
AutoReadLock lock(mSubstitutionsLock);
|
||||
SubstitutionEntry entry;
|
||||
if (mSubstitutions.Get(root, &entry)) {
|
||||
nsCOMPtr<nsIURI> baseURI = entry.baseURI;
|
||||
baseURI.forget(result);
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t flags;
|
||||
|
@ -526,10 +535,15 @@ nsresult SubstitutingProtocolHandler::GetSubstitutionFlags(
|
|||
#endif
|
||||
|
||||
*flags = 0;
|
||||
SubstitutionEntry entry;
|
||||
if (mSubstitutions.Get(root, &entry)) {
|
||||
*flags = entry.flags;
|
||||
return NS_OK;
|
||||
|
||||
{
|
||||
AutoReadLock lock(mSubstitutionsLock);
|
||||
|
||||
SubstitutionEntry entry;
|
||||
if (mSubstitutions.Get(root, &entry)) {
|
||||
*flags = entry.flags;
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIURI> baseURI;
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#include "nsJARURI.h"
|
||||
#include "mozilla/chrome/RegistryMessageUtils.h"
|
||||
#include "mozilla/Maybe.h"
|
||||
#include "mozilla/RWLock.h"
|
||||
|
||||
class nsIIOService;
|
||||
|
||||
|
@ -32,14 +33,18 @@ class SubstitutingProtocolHandler {
|
|||
bool aEnforceFileOrJar = true);
|
||||
explicit SubstitutingProtocolHandler(const char* aScheme);
|
||||
|
||||
NS_INLINE_DECL_REFCOUNTING(SubstitutingProtocolHandler);
|
||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(SubstitutingProtocolHandler);
|
||||
NS_DECL_NON_VIRTUAL_NSIPROTOCOLHANDLER;
|
||||
NS_DECL_NON_VIRTUAL_NSISUBSTITUTINGPROTOCOLHANDLER;
|
||||
|
||||
bool HasSubstitution(const nsACString& aRoot) const {
|
||||
AutoReadLock lock(const_cast<RWLock&>(mSubstitutionsLock));
|
||||
return mSubstitutions.Get(aRoot, nullptr);
|
||||
}
|
||||
|
||||
nsresult NewURI(const nsACString& aSpec, const char* aCharset,
|
||||
nsIURI* aBaseURI, nsIURI** aResult);
|
||||
|
||||
MOZ_MUST_USE nsresult
|
||||
CollectSubstitutions(InfallibleTArray<SubstitutionMapping>& aResources);
|
||||
|
||||
|
@ -97,6 +102,8 @@ class SubstitutingProtocolHandler {
|
|||
|
||||
nsCString mScheme;
|
||||
Maybe<uint32_t> mFlags;
|
||||
|
||||
RWLock mSubstitutionsLock;
|
||||
nsDataHashtable<nsCStringHashKey, SubstitutionEntry> mSubstitutions;
|
||||
nsCOMPtr<nsIIOService> mIOService;
|
||||
|
||||
|
|
|
@ -19,6 +19,10 @@ EXPORTS.mozilla.net += [
|
|||
'SubstitutingURL.h',
|
||||
]
|
||||
|
||||
EXPORTS += [
|
||||
'nsResProtocolHandler.h',
|
||||
]
|
||||
|
||||
UNIFIED_SOURCES += [
|
||||
'ExtensionProtocolHandler.cpp',
|
||||
'nsResProtocolHandler.cpp',
|
||||
|
|
|
@ -25,6 +25,20 @@ using mozilla::dom::ContentParent;
|
|||
#define kGRE "gre"
|
||||
#define kAndroid "android"
|
||||
|
||||
mozilla::StaticRefPtr<nsResProtocolHandler> nsResProtocolHandler::sSingleton;
|
||||
|
||||
already_AddRefed<nsResProtocolHandler> nsResProtocolHandler::GetSingleton() {
|
||||
if (!sSingleton) {
|
||||
RefPtr<nsResProtocolHandler> handler = new nsResProtocolHandler();
|
||||
if (NS_WARN_IF(NS_FAILED(handler->Init()))) {
|
||||
return nullptr;
|
||||
}
|
||||
sSingleton = handler;
|
||||
ClearOnShutdown(&sSingleton);
|
||||
}
|
||||
return do_AddRef(sSingleton);
|
||||
}
|
||||
|
||||
nsresult nsResProtocolHandler::Init() {
|
||||
nsresult rv;
|
||||
rv = mozilla::Omnijar::GetURIString(mozilla::Omnijar::APP, mAppURI);
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
#ifndef nsResProtocolHandler_h___
|
||||
#define nsResProtocolHandler_h___
|
||||
|
||||
#include "SubstitutingProtocolHandler.h"
|
||||
#include "mozilla/net/SubstitutingProtocolHandler.h"
|
||||
|
||||
#include "nsIResProtocolHandler.h"
|
||||
#include "nsInterfaceHashtable.h"
|
||||
|
@ -23,6 +23,8 @@ class nsResProtocolHandler final
|
|||
NS_DECL_ISUPPORTS_INHERITED
|
||||
NS_DECL_NSIRESPROTOCOLHANDLER
|
||||
|
||||
static already_AddRefed<nsResProtocolHandler> GetSingleton();
|
||||
|
||||
NS_FORWARD_NSIPROTOCOLHANDLER(mozilla::net::SubstitutingProtocolHandler::)
|
||||
|
||||
nsResProtocolHandler()
|
||||
|
@ -32,8 +34,6 @@ class nsResProtocolHandler final
|
|||
URI_IS_POTENTIALLY_TRUSTWORTHY,
|
||||
/* aEnforceFileOrJar = */ false) {}
|
||||
|
||||
MOZ_MUST_USE nsresult Init();
|
||||
|
||||
NS_IMETHOD SetSubstitution(const nsACString& aRoot,
|
||||
nsIURI* aBaseURI) override;
|
||||
NS_IMETHOD SetSubstitutionWithFlags(const nsACString& aRoot, nsIURI* aBaseURI,
|
||||
|
@ -71,6 +71,9 @@ class nsResProtocolHandler final
|
|||
nsACString& aResult) override;
|
||||
|
||||
private:
|
||||
MOZ_MUST_USE nsresult Init();
|
||||
static mozilla::StaticRefPtr<nsResProtocolHandler> sSingleton;
|
||||
|
||||
nsCString mAppURI;
|
||||
nsCString mGREURI;
|
||||
#ifdef ANDROID
|
||||
|
|
|
@ -15,6 +15,10 @@ UNIFIED_SOURCES += [
|
|||
'nsViewSourceHandler.cpp',
|
||||
]
|
||||
|
||||
EXPORTS += [
|
||||
'nsViewSourceHandler.h',
|
||||
]
|
||||
|
||||
FINAL_LIBRARY = 'xul'
|
||||
LOCAL_INCLUDES += [
|
||||
'/netwerk/base',
|
||||
|
|
|
@ -64,9 +64,10 @@ nsViewSourceHandler::GetFlagsForURI(nsIURI* aURI, uint32_t* result) {
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsViewSourceHandler::NewURI(const nsACString& aSpec, const char* aCharset,
|
||||
nsIURI* aBaseURI, nsIURI** aResult) {
|
||||
// static
|
||||
nsresult nsViewSourceHandler::CreateNewURI(const nsACString& aSpec,
|
||||
const char* aCharset,
|
||||
nsIURI* aBaseURI, nsIURI** aResult) {
|
||||
*aResult = nullptr;
|
||||
|
||||
// Extract inner URL and normalize to ASCII. This is done to properly
|
||||
|
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче