Repository: servo/servo
File: components/script/dom/document.rs (Rust)

Code before:
        self.policy_container.borrow_mut().set_csp_list(csp_list);
    }

    pub(crate) fn get_csp_list(&self) -> Option<CspList> {
        self.policy_container.borrow().csp_list.clone()
    }

    /// <https://www.w3.org/TR/CSP/#should-block-inline>
    pub(crate) fn should_elements_inline_type_behavior_be_blocked(
        &self,
        el: &Element,
        type_: csp::InlineCheckType,
        source: &str,
    ) -> csp::CheckResult {
        let (result, violations) = match self.get_csp_list() {
            None => {
                return csp::CheckResult::Allowed;
            },
            Some(csp_list) => {
                // <https://www.w3.org/TR/CSP/#is-element-nonceable>
                let element = csp::Element {
                    // Step 1: If element does not have an attribute named "nonce", return "Not Nonceable".
                    nonce: el
                        .get_attribute(&ns!(), &local_name!("nonce"))
                        .and_then(|attr| el.is_element_nonceable(attr))
                        .map(|ref_str| Cow::Owned(ref_str)),
                };
                csp_list.should_elements_inline_type_behavior_be_blocked(&element, type_, source)
            },
        };

        self.global().report_csp_violations(violations, Some(el));

        result
    }

    /// Prevent any JS or layout from running until the corresponding call to
    /// `remove_script_and_layout_blocker`. Used to isolate periods in which
    /// the DOM is in an unstable state and should not be exposed to arbitrary
    /// web content. Any attempts to invoke content JS or query layout during
    /// that time will trigger a panic. `add_delayed_task` will cause the
    /// provided task to be executed as soon as the last blocker is removed.
    pub(crate) fn add_script_and_layout_blocker(&self) {
        self.script_and_layout_blockers
            .set(self.script_and_layout_blockers.get() + 1);
    }

    /// Terminate the period in which JS or layout is disallowed from running.
    /// If no further blockers remain, any delayed tasks in the queue will
    /// be executed in queue order until the queue is empty.
    pub(crate) fn remove_script_and_layout_blocker(&self) {

Review comment (suggestion):
Is there a particular reason why step 1 can't be in `Element::is_element_nonceable`?
Seems to me like you could just do 

```rust
// Step 1: If element does not have an attribute named "nonce", return "Not Nonceable".
let nonce_attribute = self.get_attribute(&ns!(), &local_name!("nonce"))?;
```

at the beginning of the function

Code after:
        self.policy_container.borrow_mut().set_csp_list(csp_list);
    }

    pub(crate) fn get_csp_list(&self) -> Option<CspList> {
        self.policy_container.borrow().csp_list.clone()
    }

    /// <https://www.w3.org/TR/CSP/#should-block-inline>
    pub(crate) fn should_elements_inline_type_behavior_be_blocked(
        &self,
        el: &Element,
        type_: csp::InlineCheckType,
        source: &str,
    ) -> csp::CheckResult {
        let (result, violations) = match self.get_csp_list() {
            None => {
                return csp::CheckResult::Allowed;
            },
            Some(csp_list) => {
                let element = csp::Element {
                    nonce: el.nonce_attribute_if_nonceable().map(Cow::Owned),
                };
                csp_list.should_elements_inline_type_behavior_be_blocked(&element, type_, source)
            },
        };

        self.global().report_csp_violations(violations, Some(el));

        result
    }

    /// Prevent any JS or layout from running until the corresponding call to
    /// `remove_script_and_layout_blocker`. Used to isolate periods in which
    /// the DOM is in an unstable state and should not be exposed to arbitrary
    /// web content. Any attempts to invoke content JS or query layout during
    /// that time will trigger a panic. `add_delayed_task` will cause the
    /// provided task to be executed as soon as the last blocker is removed.
    pub(crate) fn add_script_and_layout_blocker(&self) {
        self.script_and_layout_blockers
            .set(self.script_and_layout_blockers.get() + 1);
    }

    /// Terminate the period in which JS or layout is disallowed from running.
    /// If no further blockers remain, any delayed tasks in the queue will
    /// be executed in queue order until the queue is empty.
    pub(crate) fn remove_script_and_layout_blocker(&self) {
        assert!(self.script_and_layout_blockers.get() > 0);
        self.script_and_layout_blockers
            .set(self.script_and_layout_blockers.get() - 1);
        while self.script_and_layout_blockers.get() == 0 && !self.delayed_tasks.borrow().is_empty()
        {