зеркало из https://github.com/mozilla/gecko-dev.git
merge mozilla-central to mozilla-inbound. r=merge a=merge
This commit is contained in:
Коммит
0350c346f6
|
@ -120,7 +120,7 @@ exports.isIdentity = isIdentity;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the transformation matrix for the given node, relative to the ancestor passed
|
* Returns the transformation matrix for the given node, relative to the ancestor passed
|
||||||
* as second argument.
|
* as second argument; considering the ancestor transformation too.
|
||||||
* If no ancestor is specified, it will returns the transformation matrix relative to the
|
* If no ancestor is specified, it will returns the transformation matrix relative to the
|
||||||
* node's parent element.
|
* node's parent element.
|
||||||
*
|
*
|
||||||
|
@ -132,7 +132,8 @@ exports.isIdentity = isIdentity;
|
||||||
* The transformation matrix.
|
* The transformation matrix.
|
||||||
*/
|
*/
|
||||||
function getNodeTransformationMatrix(node, ancestor = node.parentElement) {
|
function getNodeTransformationMatrix(node, ancestor = node.parentElement) {
|
||||||
let { a, b, c, d, e, f } = node.getTransformToAncestor(ancestor);
|
let { a, b, c, d, e, f } = ancestor.getTransformToParent()
|
||||||
|
.multiply(node.getTransformToAncestor(ancestor));
|
||||||
|
|
||||||
return [
|
return [
|
||||||
a, c, e,
|
a, c, e,
|
||||||
|
|
|
@ -36,6 +36,16 @@
|
||||||
{ css: ". {}", error: "Expected identifier for class selector but found ‘ ’. Ruleset ignored due to bad selector." },
|
{ css: ". {}", error: "Expected identifier for class selector but found ‘ ’. Ruleset ignored due to bad selector." },
|
||||||
|
|
||||||
{ css: ":not() {}", error: "Missing argument in negation pseudo-class ‘)’. Ruleset ignored due to bad selector." },
|
{ css: ":not() {}", error: "Missing argument in negation pseudo-class ‘)’. Ruleset ignored due to bad selector." },
|
||||||
|
|
||||||
|
{ css: "@media (totally-unknown-feature) {}", error: "Expected media feature name but found ‘totally-unknown-feature’." },
|
||||||
|
{ css: "@media \"foo\" {}", error: "Expected identifier in media list but found ‘\"foo\"’." },
|
||||||
|
{ css: "@media (min-width) {}", error: "Media features with min- or max- must have a value." },
|
||||||
|
{ css: "@media (device-height: -1px) {}", error: "Found invalid value for media feature." },
|
||||||
|
{ css: "@media (min-width: -1px) {}", error: "Found invalid value for media feature." },
|
||||||
|
{ css: "@media (min-resolution: 2) {}", error: "Found invalid value for media feature." },
|
||||||
|
{ css: "@media (min-monochrome: 1.1) {}", error: "Found invalid value for media feature." },
|
||||||
|
{ css: "@media (min-aspect-ratio: 1) {}", error: "Found invalid value for media feature." },
|
||||||
|
{ css: "@media (orientation: invalid-orientation-value) {}", error: "Found invalid value for media feature." },
|
||||||
];
|
];
|
||||||
|
|
||||||
var test = -1;
|
var test = -1;
|
||||||
|
|
|
@ -231,7 +231,7 @@ import java.net.URISyntaxException;
|
||||||
|
|
||||||
private UpdatePageDomainAsyncTask(final Context context, final TextView pageDomainView, final URI uri,
|
private UpdatePageDomainAsyncTask(final Context context, final TextView pageDomainView, final URI uri,
|
||||||
final String[] pageDomainTextReference) {
|
final String[] pageDomainTextReference) {
|
||||||
super(context, uri, true, 0); // baseDomain.
|
super(context, uri, true, 1); // subdomain.domain.tld.
|
||||||
this.pageDomainViewWeakReference = new WeakReference<>(pageDomainView);
|
this.pageDomainViewWeakReference = new WeakReference<>(pageDomainView);
|
||||||
this.pageDomainTextReference = pageDomainTextReference;
|
this.pageDomainTextReference = pageDomainTextReference;
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,6 +19,7 @@ import org.mozilla.gecko.activitystream.Utils;
|
||||||
import org.mozilla.gecko.activitystream.homepanel.StreamHighlightItemRowContextMenuListener;
|
import org.mozilla.gecko.activitystream.homepanel.StreamHighlightItemRowContextMenuListener;
|
||||||
import org.mozilla.gecko.activitystream.homepanel.model.WebpageRowModel;
|
import org.mozilla.gecko.activitystream.homepanel.model.WebpageRowModel;
|
||||||
import org.mozilla.gecko.util.DrawableUtil;
|
import org.mozilla.gecko.util.DrawableUtil;
|
||||||
|
import org.mozilla.gecko.util.StringUtils;
|
||||||
import org.mozilla.gecko.util.TouchTargetUtil;
|
import org.mozilla.gecko.util.TouchTargetUtil;
|
||||||
import org.mozilla.gecko.util.URIUtils;
|
import org.mozilla.gecko.util.URIUtils;
|
||||||
import org.mozilla.gecko.util.ViewUtil;
|
import org.mozilla.gecko.util.ViewUtil;
|
||||||
|
@ -144,7 +145,7 @@ public class WebpageItemRow extends StreamViewHolder {
|
||||||
private final UUID viewTagAtStart;
|
private final UUID viewTagAtStart;
|
||||||
|
|
||||||
UpdatePageDomainAsyncTask(final Context contextReference, final URI uri, final TextView pageDomainView) {
|
UpdatePageDomainAsyncTask(final Context contextReference, final URI uri, final TextView pageDomainView) {
|
||||||
super(contextReference, uri, false, 0); // hostSLD.
|
super(contextReference, uri, false, 1); // subdomain.domain.
|
||||||
this.pageDomainViewWeakReference = new WeakReference<>(pageDomainView);
|
this.pageDomainViewWeakReference = new WeakReference<>(pageDomainView);
|
||||||
|
|
||||||
// See isTagSameAsStartTag for details.
|
// See isTagSameAsStartTag for details.
|
||||||
|
@ -153,17 +154,17 @@ public class WebpageItemRow extends StreamViewHolder {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onPostExecute(final String hostSLD) {
|
protected void onPostExecute(final String domainTitle) {
|
||||||
super.onPostExecute(hostSLD);
|
super.onPostExecute(domainTitle);
|
||||||
final TextView viewToUpdate = pageDomainViewWeakReference.get();
|
final TextView viewToUpdate = pageDomainViewWeakReference.get();
|
||||||
|
|
||||||
if (viewToUpdate == null || !isTagSameAsStartTag(viewToUpdate)) {
|
if (viewToUpdate == null || !isTagSameAsStartTag(viewToUpdate)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// hostSLD will be the empty String if the host cannot be determined. This is fine: it's very unlikely
|
// The title will be the empty String if the host cannot be determined. This is fine: it's very unlikely
|
||||||
// and the page title will be URL if there's an error there so we wouldn't want to write the URL again here.
|
// and the page title will be URL if there's an error there so we wouldn't want to write the URL again here.
|
||||||
viewToUpdate.setText(hostSLD);
|
viewToUpdate.setText(StringUtils.stripCommonSubdomains(domainTitle));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -1140,4 +1140,4 @@ static const TransportSecurityPreload kPublicKeyPinningPreloadList[] = {
|
||||||
|
|
||||||
static const int32_t kUnknownId = -1;
|
static const int32_t kUnknownId = -1;
|
||||||
|
|
||||||
static const PRTime kPreloadPKPinsExpirationTime = INT64_C(1513358056232000);
|
static const PRTime kPreloadPKPinsExpirationTime = INT64_C(1513444695639000);
|
||||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -1067,6 +1067,10 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
|
||||||
debug!("constellation got URL load message from script");
|
debug!("constellation got URL load message from script");
|
||||||
self.handle_load_url_msg(source_top_ctx_id, source_pipeline_id, load_data, replace);
|
self.handle_load_url_msg(source_top_ctx_id, source_pipeline_id, load_data, replace);
|
||||||
}
|
}
|
||||||
|
FromScriptMsg::AbortLoadUrl => {
|
||||||
|
debug!("constellation got abort URL load message from script");
|
||||||
|
self.handle_abort_load_url_msg(source_pipeline_id);
|
||||||
|
}
|
||||||
// A page loaded has completed all parsing, script, and reflow messages have been sent.
|
// A page loaded has completed all parsing, script, and reflow messages have been sent.
|
||||||
FromScriptMsg::LoadComplete => {
|
FromScriptMsg::LoadComplete => {
|
||||||
debug!("constellation got load complete message");
|
debug!("constellation got load complete message");
|
||||||
|
@ -1891,6 +1895,18 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn handle_abort_load_url_msg(&mut self, new_pipeline_id: PipelineId) {
|
||||||
|
let pending_index = self.pending_changes.iter().rposition(|change| {
|
||||||
|
change.new_pipeline_id == new_pipeline_id
|
||||||
|
});
|
||||||
|
|
||||||
|
// If it is found, remove it from the pending changes.
|
||||||
|
if let Some(pending_index) = pending_index {
|
||||||
|
self.pending_changes.remove(pending_index);
|
||||||
|
self.close_pipeline(new_pipeline_id, DiscardBrowsingContext::No, ExitPipelineMode::Normal);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn handle_load_start_msg(&mut self, top_level_browsing_context_id: TopLevelBrowsingContextId,
|
fn handle_load_start_msg(&mut self, top_level_browsing_context_id: TopLevelBrowsingContextId,
|
||||||
pipeline_id: PipelineId) {
|
pipeline_id: PipelineId) {
|
||||||
if self.pipelines.get(&pipeline_id).and_then(|p| p.parent_info).is_none() {
|
if self.pipelines.get(&pipeline_id).and_then(|p| p.parent_info).is_none() {
|
||||||
|
|
|
@ -44,7 +44,7 @@ use msg::constellation_msg::{FrameType, BrowsingContextId, PipelineId, TopLevelB
|
||||||
use net_traits::response::HttpsState;
|
use net_traits::response::HttpsState;
|
||||||
use script_layout_interface::message::ReflowQueryType;
|
use script_layout_interface::message::ReflowQueryType;
|
||||||
use script_thread::{ScriptThread, Runnable};
|
use script_thread::{ScriptThread, Runnable};
|
||||||
use script_traits::{IFrameLoadInfo, IFrameLoadInfoWithData, LoadData, UpdatePipelineIdReason};
|
use script_traits::{IFrameLoadInfo, IFrameLoadInfoWithData, JsEvalResult, LoadData, UpdatePipelineIdReason};
|
||||||
use script_traits::{MozBrowserEvent, NewLayoutInfo, ScriptMsg};
|
use script_traits::{MozBrowserEvent, NewLayoutInfo, ScriptMsg};
|
||||||
use script_traits::IFrameSandboxState::{IFrameSandboxed, IFrameUnsandboxed};
|
use script_traits::IFrameSandboxState::{IFrameSandboxed, IFrameUnsandboxed};
|
||||||
use servo_atoms::Atom;
|
use servo_atoms::Atom;
|
||||||
|
@ -114,7 +114,7 @@ impl HTMLIFrameElement {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn navigate_or_reload_child_browsing_context(&self,
|
pub fn navigate_or_reload_child_browsing_context(&self,
|
||||||
load_data: Option<LoadData>,
|
mut load_data: Option<LoadData>,
|
||||||
nav_type: NavigationType,
|
nav_type: NavigationType,
|
||||||
replace: bool) {
|
replace: bool) {
|
||||||
let sandboxed = if self.is_sandboxed() {
|
let sandboxed = if self.is_sandboxed() {
|
||||||
|
@ -140,12 +140,27 @@ impl HTMLIFrameElement {
|
||||||
// document; the new navigation will continue blocking it.
|
// document; the new navigation will continue blocking it.
|
||||||
LoadBlocker::terminate(&mut load_blocker);
|
LoadBlocker::terminate(&mut load_blocker);
|
||||||
|
|
||||||
|
if let Some(ref mut load_data) = load_data {
|
||||||
|
let is_javascript = load_data.url.scheme() == "javascript";
|
||||||
|
if is_javascript {
|
||||||
|
let window_proxy = self.GetContentWindow();
|
||||||
|
if let Some(window_proxy) = window_proxy {
|
||||||
|
ScriptThread::eval_js_url(&window_proxy.global(), load_data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//TODO(#9592): Deal with the case where an iframe is being reloaded so url is None.
|
//TODO(#9592): Deal with the case where an iframe is being reloaded so url is None.
|
||||||
// The iframe should always have access to the nested context's active
|
// The iframe should always have access to the nested context's active
|
||||||
// document URL through the browsing context.
|
// document URL through the browsing context.
|
||||||
if let Some(ref load_data) = load_data {
|
if let Some(ref load_data) = load_data {
|
||||||
|
match load_data.js_eval_result {
|
||||||
|
Some(JsEvalResult::NoContent) => (),
|
||||||
|
_ => {
|
||||||
*load_blocker = Some(LoadBlocker::new(&*document, LoadType::Subframe(load_data.url.clone())));
|
*load_blocker = Some(LoadBlocker::new(&*document, LoadType::Subframe(load_data.url.clone())));
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
let window = window_from_node(self);
|
let window = window_from_node(self);
|
||||||
let old_pipeline_id = self.pipeline_id();
|
let old_pipeline_id = self.pipeline_id();
|
||||||
|
|
|
@ -89,8 +89,8 @@ use script_runtime::{CommonScriptMsg, ScriptChan, ScriptThreadEventCategory};
|
||||||
use script_runtime::{ScriptPort, StackRootTLS, get_reports, new_rt_and_cx};
|
use script_runtime::{ScriptPort, StackRootTLS, get_reports, new_rt_and_cx};
|
||||||
use script_traits::{CompositorEvent, ConstellationControlMsg, PaintMetricType};
|
use script_traits::{CompositorEvent, ConstellationControlMsg, PaintMetricType};
|
||||||
use script_traits::{DocumentActivity, DiscardBrowsingContext, EventResult};
|
use script_traits::{DocumentActivity, DiscardBrowsingContext, EventResult};
|
||||||
use script_traits::{InitialScriptState, LayoutMsg, LoadData, MouseButton, MouseEventType, MozBrowserEvent};
|
use script_traits::{InitialScriptState, JsEvalResult, LayoutMsg, LoadData, MouseButton, MouseEventType};
|
||||||
use script_traits::{NewLayoutInfo, ScriptToConstellationChan, ScriptMsg, UpdatePipelineIdReason};
|
use script_traits::{MozBrowserEvent, NewLayoutInfo, ScriptToConstellationChan, ScriptMsg, UpdatePipelineIdReason};
|
||||||
use script_traits::{ScriptThreadFactory, TimerEvent, TimerSchedulerMsg, TimerSource};
|
use script_traits::{ScriptThreadFactory, TimerEvent, TimerSchedulerMsg, TimerSource};
|
||||||
use script_traits::{TouchEventType, TouchId, UntrustedNodeAddress, WindowSizeData, WindowSizeType};
|
use script_traits::{TouchEventType, TouchId, UntrustedNodeAddress, WindowSizeData, WindowSizeType};
|
||||||
use script_traits::CompositorEvent::{KeyEvent, MouseButtonEvent, MouseMoveEvent, ResizeEvent};
|
use script_traits::CompositorEvent::{KeyEvent, MouseButtonEvent, MouseMoveEvent, ResizeEvent};
|
||||||
|
@ -122,6 +122,7 @@ use task_source::performance_timeline::PerformanceTimelineTaskSource;
|
||||||
use task_source::user_interaction::UserInteractionTaskSource;
|
use task_source::user_interaction::UserInteractionTaskSource;
|
||||||
use time::{get_time, precise_time_ns, Tm};
|
use time::{get_time, precise_time_ns, Tm};
|
||||||
use url::Position;
|
use url::Position;
|
||||||
|
use url::percent_encoding::percent_decode;
|
||||||
use webdriver_handlers;
|
use webdriver_handlers;
|
||||||
use webvr_traits::{WebVREvent, WebVRMsg};
|
use webvr_traits::{WebVREvent, WebVRMsg};
|
||||||
|
|
||||||
|
@ -1509,7 +1510,7 @@ impl ScriptThread {
|
||||||
load_data.url.clone(),
|
load_data.url.clone(),
|
||||||
origin);
|
origin);
|
||||||
if load_data.url.as_str() == "about:blank" {
|
if load_data.url.as_str() == "about:blank" {
|
||||||
self.start_page_load_about_blank(new_load);
|
self.start_page_load_about_blank(new_load, load_data.js_eval_result);
|
||||||
} else {
|
} else {
|
||||||
self.pre_page_load(new_load, load_data);
|
self.pre_page_load(new_load, load_data);
|
||||||
}
|
}
|
||||||
|
@ -1679,6 +1680,18 @@ impl ScriptThread {
|
||||||
// the pipeline exited before the page load completed.
|
// the pipeline exited before the page load completed.
|
||||||
match idx {
|
match idx {
|
||||||
Some(idx) => {
|
Some(idx) => {
|
||||||
|
// https://html.spec.whatwg.org/multipage/#process-a-navigate-response
|
||||||
|
// 2. If response's status is 204 or 205, then abort these steps.
|
||||||
|
match metadata {
|
||||||
|
Some(Metadata { status: Some((204 ... 205, _)), .. }) => {
|
||||||
|
self.script_sender
|
||||||
|
.send((id.clone(), ScriptMsg::AbortLoadUrl))
|
||||||
|
.unwrap();
|
||||||
|
return None;
|
||||||
|
},
|
||||||
|
_ => ()
|
||||||
|
};
|
||||||
|
|
||||||
let load = self.incomplete_loads.borrow_mut().remove(idx);
|
let load = self.incomplete_loads.borrow_mut().remove(idx);
|
||||||
metadata.map(|meta| self.load(meta, load))
|
metadata.map(|meta| self.load(meta, load))
|
||||||
}
|
}
|
||||||
|
@ -2118,39 +2131,7 @@ impl ScriptThread {
|
||||||
// Notify devtools that a new script global exists.
|
// Notify devtools that a new script global exists.
|
||||||
self.notify_devtools(document.Title(), final_url.clone(), (incomplete.pipeline_id, None));
|
self.notify_devtools(document.Title(), final_url.clone(), (incomplete.pipeline_id, None));
|
||||||
|
|
||||||
let is_javascript = incomplete.url.scheme() == "javascript";
|
let parse_input = DOMString::new();
|
||||||
let parse_input = if is_javascript {
|
|
||||||
use url::percent_encoding::percent_decode;
|
|
||||||
|
|
||||||
// Turn javascript: URL into JS code to eval, according to the steps in
|
|
||||||
// https://html.spec.whatwg.org/multipage/#javascript-protocol
|
|
||||||
|
|
||||||
// This slice of the URL’s serialization is equivalent to (5.) to (7.):
|
|
||||||
// Start with the scheme data of the parsed URL;
|
|
||||||
// append question mark and query component, if any;
|
|
||||||
// append number sign and fragment component if any.
|
|
||||||
let encoded = &incomplete.url[Position::BeforePath..];
|
|
||||||
|
|
||||||
// Percent-decode (8.) and UTF-8 decode (9.)
|
|
||||||
let script_source = percent_decode(encoded.as_bytes()).decode_utf8_lossy();
|
|
||||||
|
|
||||||
// Script source is ready to be evaluated (11.)
|
|
||||||
unsafe {
|
|
||||||
let _ac = JSAutoCompartment::new(self.get_cx(), window.reflector().get_jsobject().get());
|
|
||||||
rooted!(in(self.get_cx()) let mut jsval = UndefinedValue());
|
|
||||||
window.upcast::<GlobalScope>().evaluate_js_on_global_with_result(
|
|
||||||
&script_source, jsval.handle_mut());
|
|
||||||
let strval = DOMString::from_jsval(self.get_cx(),
|
|
||||||
jsval.handle(),
|
|
||||||
StringificationBehavior::Empty);
|
|
||||||
match strval {
|
|
||||||
Ok(ConversionResult::Success(s)) => s,
|
|
||||||
_ => DOMString::new(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
DOMString::new()
|
|
||||||
};
|
|
||||||
|
|
||||||
document.set_https_state(metadata.https_state);
|
document.set_https_state(metadata.https_state);
|
||||||
|
|
||||||
|
@ -2329,8 +2310,16 @@ impl ScriptThread {
|
||||||
/// for the given pipeline (specifically the "navigate" algorithm).
|
/// for the given pipeline (specifically the "navigate" algorithm).
|
||||||
fn handle_navigate(&self, parent_pipeline_id: PipelineId,
|
fn handle_navigate(&self, parent_pipeline_id: PipelineId,
|
||||||
browsing_context_id: Option<BrowsingContextId>,
|
browsing_context_id: Option<BrowsingContextId>,
|
||||||
load_data: LoadData,
|
mut load_data: LoadData,
|
||||||
replace: bool) {
|
replace: bool) {
|
||||||
|
let is_javascript = load_data.url.scheme() == "javascript";
|
||||||
|
if is_javascript {
|
||||||
|
let window = self.documents.borrow().find_window(parent_pipeline_id);
|
||||||
|
if let Some(window) = window {
|
||||||
|
ScriptThread::eval_js_url(window.upcast::<GlobalScope>(), &mut load_data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
match browsing_context_id {
|
match browsing_context_id {
|
||||||
Some(browsing_context_id) => {
|
Some(browsing_context_id) => {
|
||||||
let iframe = self.documents.borrow().find_iframe(parent_pipeline_id, browsing_context_id);
|
let iframe = self.documents.borrow().find_iframe(parent_pipeline_id, browsing_context_id);
|
||||||
|
@ -2346,6 +2335,43 @@ impl ScriptThread {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn eval_js_url(global_scope: &GlobalScope, load_data: &mut LoadData) {
|
||||||
|
// Turn javascript: URL into JS code to eval, according to the steps in
|
||||||
|
// https://html.spec.whatwg.org/multipage/#javascript-protocol
|
||||||
|
|
||||||
|
// This slice of the URL’s serialization is equivalent to (5.) to (7.):
|
||||||
|
// Start with the scheme data of the parsed URL;
|
||||||
|
// append question mark and query component, if any;
|
||||||
|
// append number sign and fragment component if any.
|
||||||
|
let encoded = &load_data.url.clone()[Position::BeforePath..];
|
||||||
|
|
||||||
|
// Percent-decode (8.) and UTF-8 decode (9.)
|
||||||
|
let script_source = percent_decode(encoded.as_bytes()).decode_utf8_lossy();
|
||||||
|
|
||||||
|
// Script source is ready to be evaluated (11.)
|
||||||
|
let _ac = JSAutoCompartment::new(global_scope.get_cx(), global_scope.reflector().get_jsobject().get());
|
||||||
|
rooted!(in(global_scope.get_cx()) let mut jsval = UndefinedValue());
|
||||||
|
global_scope.evaluate_js_on_global_with_result(&script_source, jsval.handle_mut());
|
||||||
|
|
||||||
|
load_data.js_eval_result = if jsval.get().is_string() {
|
||||||
|
unsafe {
|
||||||
|
let strval = DOMString::from_jsval(global_scope.get_cx(),
|
||||||
|
jsval.handle(),
|
||||||
|
StringificationBehavior::Empty);
|
||||||
|
match strval {
|
||||||
|
Ok(ConversionResult::Success(s)) => {
|
||||||
|
Some(JsEvalResult::Ok(String::from(s).as_bytes().to_vec()))
|
||||||
|
},
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Some(JsEvalResult::NoContent)
|
||||||
|
};
|
||||||
|
|
||||||
|
load_data.url = ServoUrl::parse("about:blank").unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
fn handle_resize_event(&self, pipeline_id: PipelineId, new_size: WindowSizeData, size_type: WindowSizeType) {
|
fn handle_resize_event(&self, pipeline_id: PipelineId, new_size: WindowSizeData, size_type: WindowSizeType) {
|
||||||
let document = match { self.documents.borrow().find_document(pipeline_id) } {
|
let document = match { self.documents.borrow().find_document(pipeline_id) } {
|
||||||
Some(document) => document,
|
Some(document) => document,
|
||||||
|
@ -2377,7 +2403,7 @@ impl ScriptThread {
|
||||||
/// argument until a notification is received that the fetch is complete.
|
/// argument until a notification is received that the fetch is complete.
|
||||||
fn pre_page_load(&self, incomplete: InProgressLoad, load_data: LoadData) {
|
fn pre_page_load(&self, incomplete: InProgressLoad, load_data: LoadData) {
|
||||||
let id = incomplete.pipeline_id.clone();
|
let id = incomplete.pipeline_id.clone();
|
||||||
let mut req_init = RequestInit {
|
let req_init = RequestInit {
|
||||||
url: load_data.url.clone(),
|
url: load_data.url.clone(),
|
||||||
method: load_data.method,
|
method: load_data.method,
|
||||||
destination: Destination::Document,
|
destination: Destination::Document,
|
||||||
|
@ -2393,10 +2419,6 @@ impl ScriptThread {
|
||||||
.. RequestInit::default()
|
.. RequestInit::default()
|
||||||
};
|
};
|
||||||
|
|
||||||
if req_init.url.scheme() == "javascript" {
|
|
||||||
req_init.url = ServoUrl::parse("about:blank").unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
let context = ParserContext::new(id, load_data.url);
|
let context = ParserContext::new(id, load_data.url);
|
||||||
self.incomplete_parser_contexts.borrow_mut().push((id, context));
|
self.incomplete_parser_contexts.borrow_mut().push((id, context));
|
||||||
|
|
||||||
|
@ -2436,7 +2458,7 @@ impl ScriptThread {
|
||||||
|
|
||||||
/// Synchronously fetch `about:blank`. Stores the `InProgressLoad`
|
/// Synchronously fetch `about:blank`. Stores the `InProgressLoad`
|
||||||
/// argument until a notification is received that the fetch is complete.
|
/// argument until a notification is received that the fetch is complete.
|
||||||
fn start_page_load_about_blank(&self, incomplete: InProgressLoad) {
|
fn start_page_load_about_blank(&self, incomplete: InProgressLoad, js_eval_result: Option<JsEvalResult>) {
|
||||||
let id = incomplete.pipeline_id;
|
let id = incomplete.pipeline_id;
|
||||||
|
|
||||||
self.incomplete_loads.borrow_mut().push(incomplete);
|
self.incomplete_loads.borrow_mut().push(incomplete);
|
||||||
|
@ -2446,8 +2468,20 @@ impl ScriptThread {
|
||||||
|
|
||||||
let mut meta = Metadata::default(url);
|
let mut meta = Metadata::default(url);
|
||||||
meta.set_content_type(Some(&mime!(Text / Html)));
|
meta.set_content_type(Some(&mime!(Text / Html)));
|
||||||
|
|
||||||
|
// If this page load is the result of a javascript scheme url, map
|
||||||
|
// the evaluation result into a response.
|
||||||
|
let chunk = match js_eval_result {
|
||||||
|
Some(JsEvalResult::Ok(content)) => content,
|
||||||
|
Some(JsEvalResult::NoContent) => {
|
||||||
|
meta.status = Some((204, b"No Content".to_vec()));
|
||||||
|
vec![]
|
||||||
|
},
|
||||||
|
None => vec![]
|
||||||
|
};
|
||||||
|
|
||||||
context.process_response(Ok(FetchMetadata::Unfiltered(meta)));
|
context.process_response(Ok(FetchMetadata::Unfiltered(meta)));
|
||||||
context.process_response_chunk(vec![]);
|
context.process_response_chunk(chunk);
|
||||||
context.process_response_eof(Ok(()));
|
context.process_response_eof(Ok(()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -146,12 +146,24 @@ pub struct LoadData {
|
||||||
pub headers: Headers,
|
pub headers: Headers,
|
||||||
/// The data.
|
/// The data.
|
||||||
pub data: Option<Vec<u8>>,
|
pub data: Option<Vec<u8>>,
|
||||||
|
/// The result of evaluating a javascript scheme url.
|
||||||
|
pub js_eval_result: Option<JsEvalResult>,
|
||||||
/// The referrer policy.
|
/// The referrer policy.
|
||||||
pub referrer_policy: Option<ReferrerPolicy>,
|
pub referrer_policy: Option<ReferrerPolicy>,
|
||||||
/// The referrer URL.
|
/// The referrer URL.
|
||||||
pub referrer_url: Option<ServoUrl>,
|
pub referrer_url: Option<ServoUrl>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// The result of evaluating a javascript scheme url.
|
||||||
|
#[derive(Clone, Debug, Deserialize, Serialize)]
|
||||||
|
pub enum JsEvalResult {
|
||||||
|
/// The js evaluation had a non-string result, 204 status code.
|
||||||
|
/// https://html.spec.whatwg.org/multipage/#navigate 12.11
|
||||||
|
NoContent,
|
||||||
|
/// The js evaluation had a string result.
|
||||||
|
Ok(Vec<u8>)
|
||||||
|
}
|
||||||
|
|
||||||
impl LoadData {
|
impl LoadData {
|
||||||
/// Create a new `LoadData` object.
|
/// Create a new `LoadData` object.
|
||||||
pub fn new(url: ServoUrl,
|
pub fn new(url: ServoUrl,
|
||||||
|
@ -165,6 +177,7 @@ impl LoadData {
|
||||||
method: Method::Get,
|
method: Method::Get,
|
||||||
headers: Headers::new(),
|
headers: Headers::new(),
|
||||||
data: None,
|
data: None,
|
||||||
|
js_eval_result: None,
|
||||||
referrer_policy: referrer_policy,
|
referrer_policy: referrer_policy,
|
||||||
referrer_url: referrer_url,
|
referrer_url: referrer_url,
|
||||||
}
|
}
|
||||||
|
|
|
@ -99,6 +99,8 @@ pub enum ScriptMsg {
|
||||||
/// A new load has been requested, with an option to replace the current entry once loaded
|
/// A new load has been requested, with an option to replace the current entry once loaded
|
||||||
/// instead of adding a new entry.
|
/// instead of adding a new entry.
|
||||||
LoadUrl(LoadData, bool),
|
LoadUrl(LoadData, bool),
|
||||||
|
/// Abort loading after sending a LoadUrl message.
|
||||||
|
AbortLoadUrl,
|
||||||
/// Post a message to the currently active window of a given browsing context.
|
/// Post a message to the currently active window of a given browsing context.
|
||||||
PostMessage(BrowsingContextId, Option<ImmutableOrigin>, Vec<u8>),
|
PostMessage(BrowsingContextId, Option<ImmutableOrigin>, Vec<u8>),
|
||||||
/// Dispatch a mozbrowser event to the parent of a mozbrowser iframe.
|
/// Dispatch a mozbrowser event to the parent of a mozbrowser iframe.
|
||||||
|
|
|
@ -299,7 +299,10 @@ impl<T: SelectorMapEntry> SelectorMap<T> {
|
||||||
// rulehash lookup may produce superfluous selectors, but the
|
// rulehash lookup may produce superfluous selectors, but the
|
||||||
// subsequent selector matching work will filter them out.
|
// subsequent selector matching work will filter them out.
|
||||||
if name != lower_name {
|
if name != lower_name {
|
||||||
find_push(&mut self.local_name_hash, lower_name.clone(), entry.clone());
|
self.local_name_hash
|
||||||
|
.entry(lower_name.clone())
|
||||||
|
.or_insert_with(SmallVec::new)
|
||||||
|
.push(entry.clone());
|
||||||
}
|
}
|
||||||
self.local_name_hash
|
self.local_name_hash
|
||||||
.entry(name.clone())
|
.entry(name.clone())
|
||||||
|
@ -485,15 +488,6 @@ fn find_bucket<'a>(mut iter: SelectorIter<'a, SelectorImpl>) -> Bucket<'a> {
|
||||||
return current_bucket
|
return current_bucket
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn find_push<Str: Eq + Hash, V, VL>(map: &mut PrecomputedHashMap<Str, VL>,
|
|
||||||
key: Str,
|
|
||||||
value: V)
|
|
||||||
where VL: VecLike<V> + Default
|
|
||||||
{
|
|
||||||
map.entry(key).or_insert_with(VL::default).push(value)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Wrapper for PrecomputedHashMap that does ASCII-case-insensitive lookup in quirks mode.
|
/// Wrapper for PrecomputedHashMap that does ASCII-case-insensitive lookup in quirks mode.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
||||||
|
|
Загрузка…
Ссылка в новой задаче