1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138
|
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use devtools_traits::{ConsoleMessage, LogLevel, ScriptToDevtoolsControlMsg};
use dom::bindings::inheritance::Castable;
use dom::bindings::str::DOMString;
use dom::globalscope::GlobalScope;
use dom::workerglobalscope::WorkerGlobalScope;
use std::io;
// https://developer.mozilla.org/en-US/docs/Web/API/Console
pub struct Console(());
impl Console {
fn send_to_devtools(global: &GlobalScope, level: LogLevel, message: DOMString) {
if let Some(chan) = global.devtools_chan() {
let console_message = prepare_message(level, message);
let worker_id = global.downcast::<WorkerGlobalScope>().map(|worker| {
worker.get_worker_id()
});
let devtools_message = ScriptToDevtoolsControlMsg::ConsoleAPI(
global.pipeline_id(),
console_message,
worker_id);
chan.send(devtools_message).unwrap();
}
}
}
// In order to avoid interleaving the stdout output of the Console API methods
// with stderr that could be in use on other threads, we lock stderr until
// we're finished with stdout. Since the stderr lock is reentrant, there is
// no risk of deadlock if the callback ends up trying to write to stderr for
// any reason.
fn with_stderr_lock<F>(f: F) where F: FnOnce() {
let stderr = io::stderr();
let _handle = stderr.lock();
f()
}
impl Console {
// https://developer.mozilla.org/en-US/docs/Web/API/Console/log
pub fn Log(global: &GlobalScope, messages: Vec<DOMString>) {
with_stderr_lock(move || {
for message in messages {
println!("{}", message);
Self::send_to_devtools(global, LogLevel::Log, message);
}
})
}
// https://developer.mozilla.org/en-US/docs/Web/API/Console
pub fn Debug(global: &GlobalScope, messages: Vec<DOMString>) {
with_stderr_lock(move || {
for message in messages {
println!("{}", message);
Self::send_to_devtools(global, LogLevel::Debug, message);
}
})
}
// https://developer.mozilla.org/en-US/docs/Web/API/Console/info
pub fn Info(global: &GlobalScope, messages: Vec<DOMString>) {
with_stderr_lock(move || {
for message in messages {
println!("{}", message);
Self::send_to_devtools(global, LogLevel::Info, message);
}
})
}
// https://developer.mozilla.org/en-US/docs/Web/API/Console/warn
pub fn Warn(global: &GlobalScope, messages: Vec<DOMString>) {
with_stderr_lock(move || {
for message in messages {
println!("{}", message);
Self::send_to_devtools(global, LogLevel::Warn, message);
}
})
}
// https://developer.mozilla.org/en-US/docs/Web/API/Console/error
pub fn Error(global: &GlobalScope, messages: Vec<DOMString>) {
with_stderr_lock(move || {
for message in messages {
println!("{}", message);
Self::send_to_devtools(global, LogLevel::Error, message);
}
})
}
// https://developer.mozilla.org/en-US/docs/Web/API/Console/assert
pub fn Assert(global: &GlobalScope, condition: bool, message: Option<DOMString>) {
with_stderr_lock(move || {
if !condition {
let message = message.unwrap_or_else(|| DOMString::from("no message"));
println!("Assertion failed: {}", message);
Self::send_to_devtools(global, LogLevel::Error, message);
}
})
}
// https://developer.mozilla.org/en-US/docs/Web/API/Console/time
pub fn Time(global: &GlobalScope, label: DOMString) {
with_stderr_lock(move || {
if let Ok(()) = global.time(label.clone()) {
let message = DOMString::from(format!("{}: timer started", label));
println!("{}", message);
Self::send_to_devtools(global, LogLevel::Log, message);
}
})
}
// https://developer.mozilla.org/en-US/docs/Web/API/Console/timeEnd
pub fn TimeEnd(global: &GlobalScope, label: DOMString) {
with_stderr_lock(move || {
if let Ok(delta) = global.time_end(&label) {
let message = DOMString::from(
format!("{}: {}ms", label, delta)
);
println!("{}", message);
Self::send_to_devtools(global, LogLevel::Log, message);
};
})
}
}
fn prepare_message(log_level: LogLevel, message: DOMString) -> ConsoleMessage {
// TODO: Sending fake values for filename, lineNumber and columnNumber in LogMessage; adjust later
ConsoleMessage {
message: String::from(message),
logLevel: log_level,
filename: "test".to_owned(),
lineNumber: 1,
columnNumber: 1,
}
}
|