mirror of
https://github.com/pjh456/OxideJS.git
synced 2026-10-24 02:31:13 +08:00
feat: 补齐 String Annex B HTML 包装方法族
This commit is contained in:
@@ -763,3 +763,144 @@ pub fn string_ends_with<H: VmHost>(vm: &mut H, args: &[u8]) -> NativeResult {
|
||||
let result = if search.is_empty() { true } else { s[..end_pos].ends_with(&search) };
|
||||
NativeResult::Ok(JsValue::bool(result))
|
||||
}
|
||||
|
||||
// ── Annex B HTML 方法族 ─────────────────────────────────────────────────
|
||||
//
|
||||
// 13 个 HTML 包装方法共用 CreateHTML 语义:this 经 RequireObjectCoercible +
|
||||
// ToString 后拼 `<tag attr="值">串</tag>`;attr 为空串则无属性段,属性值
|
||||
// 经完整 ToString(缺参得 "undefined"),值内 0x0022(双引号)替换为
|
||||
// `"`,其余单元原样保留。
|
||||
|
||||
/// CreateHTML 语义拼接:`<tag attr="值">串</tag>` 片段;attr 为空则无属性段,
|
||||
/// 属性值内 0x0022 替换为 `"`。
|
||||
fn create_html(s: &[u16], tag: &str, attr: &str, attr_value: &[u16]) -> Vec<u16> {
|
||||
let mut out = Vec::with_capacity(s.len() + tag.len() * 2 + attr.len() + attr_value.len() * 2 + 8);
|
||||
out.push(b'<' as u16);
|
||||
out.extend(tag.encode_utf16());
|
||||
if !attr.is_empty() {
|
||||
out.push(b' ' as u16);
|
||||
out.extend(attr.encode_utf16());
|
||||
out.push(b'=' as u16);
|
||||
out.push(b'"' as u16);
|
||||
for &u in attr_value {
|
||||
if u == 0x0022 {
|
||||
out.extend(b""".iter().map(|&b| b as u16));
|
||||
} else {
|
||||
out.push(u);
|
||||
}
|
||||
}
|
||||
out.push(b'"' as u16);
|
||||
}
|
||||
out.push(b'>' as u16);
|
||||
out.extend_from_slice(s);
|
||||
out.push(b'<' as u16);
|
||||
out.push(b'/' as u16);
|
||||
out.extend(tag.encode_utf16());
|
||||
out.push(b'>' as u16);
|
||||
out
|
||||
}
|
||||
|
||||
/// `String.prototype.anchor(name)`:返回 `<a name="值">串</a>` 形 HTML 片段;
|
||||
/// 属性值经完整 ToString(缺参得 "undefined"),值内双引号替换为 `"`。
|
||||
pub fn string_anchor<H: VmHost>(vm: &mut H, args: &[u8]) -> NativeResult {
|
||||
builtins_debug!("String.prototype.anchor called with {} args", args.len());
|
||||
let s: Vec<u16> = try_string!(this_units(vm, args)).into_owned();
|
||||
let val = if args.len() > 1 { vm.reg(args[1]) } else { JsValue::undefined() };
|
||||
let v: Vec<u16> = try_string!(as_units(vm, val)).into_owned();
|
||||
NativeResult::Ok(vm.new_string_units_owned(create_html(&s, "a", "name", &v)))
|
||||
}
|
||||
|
||||
/// `String.prototype.big()`:返回 `<big>串</big>` 形 HTML 片段。
|
||||
pub fn string_big<H: VmHost>(vm: &mut H, args: &[u8]) -> NativeResult {
|
||||
builtins_debug!("String.prototype.big called with {} args", args.len());
|
||||
let s: Vec<u16> = try_string!(this_units(vm, args)).into_owned();
|
||||
NativeResult::Ok(vm.new_string_units_owned(create_html(&s, "big", "", &[])))
|
||||
}
|
||||
|
||||
/// `String.prototype.blink()`:返回 `<blink>串</blink>` 形 HTML 片段。
|
||||
pub fn string_blink<H: VmHost>(vm: &mut H, args: &[u8]) -> NativeResult {
|
||||
builtins_debug!("String.prototype.blink called with {} args", args.len());
|
||||
let s: Vec<u16> = try_string!(this_units(vm, args)).into_owned();
|
||||
NativeResult::Ok(vm.new_string_units_owned(create_html(&s, "blink", "", &[])))
|
||||
}
|
||||
|
||||
/// `String.prototype.bold()`:返回 `<b>串</b>` 形 HTML 片段。
|
||||
pub fn string_bold<H: VmHost>(vm: &mut H, args: &[u8]) -> NativeResult {
|
||||
builtins_debug!("String.prototype.bold called with {} args", args.len());
|
||||
let s: Vec<u16> = try_string!(this_units(vm, args)).into_owned();
|
||||
NativeResult::Ok(vm.new_string_units_owned(create_html(&s, "b", "", &[])))
|
||||
}
|
||||
|
||||
/// `String.prototype.fixed()`:返回 `<tt>串</tt>` 形 HTML 片段。
|
||||
pub fn string_fixed<H: VmHost>(vm: &mut H, args: &[u8]) -> NativeResult {
|
||||
builtins_debug!("String.prototype.fixed called with {} args", args.len());
|
||||
let s: Vec<u16> = try_string!(this_units(vm, args)).into_owned();
|
||||
NativeResult::Ok(vm.new_string_units_owned(create_html(&s, "tt", "", &[])))
|
||||
}
|
||||
|
||||
/// `String.prototype.fontcolor(colour)`:返回 `<font color="值">串</font>` 形
|
||||
/// HTML 片段;属性值经完整 ToString(缺参得 "undefined"),值内双引号替换为
|
||||
/// `"`。
|
||||
pub fn string_fontcolor<H: VmHost>(vm: &mut H, args: &[u8]) -> NativeResult {
|
||||
builtins_debug!("String.prototype.fontcolor called with {} args", args.len());
|
||||
let s: Vec<u16> = try_string!(this_units(vm, args)).into_owned();
|
||||
let val = if args.len() > 1 { vm.reg(args[1]) } else { JsValue::undefined() };
|
||||
let v: Vec<u16> = try_string!(as_units(vm, val)).into_owned();
|
||||
NativeResult::Ok(vm.new_string_units_owned(create_html(&s, "font", "color", &v)))
|
||||
}
|
||||
|
||||
/// `String.prototype.fontsize(size)`:返回 `<font size="值">串</font>` 形
|
||||
/// HTML 片段;属性值经完整 ToString(缺参得 "undefined"),值内双引号替换为
|
||||
/// `"`。
|
||||
pub fn string_fontsize<H: VmHost>(vm: &mut H, args: &[u8]) -> NativeResult {
|
||||
builtins_debug!("String.prototype.fontsize called with {} args", args.len());
|
||||
let s: Vec<u16> = try_string!(this_units(vm, args)).into_owned();
|
||||
let val = if args.len() > 1 { vm.reg(args[1]) } else { JsValue::undefined() };
|
||||
let v: Vec<u16> = try_string!(as_units(vm, val)).into_owned();
|
||||
NativeResult::Ok(vm.new_string_units_owned(create_html(&s, "font", "size", &v)))
|
||||
}
|
||||
|
||||
/// `String.prototype.italics()`:返回 `<i>串</i>` 形 HTML 片段。
|
||||
pub fn string_italics<H: VmHost>(vm: &mut H, args: &[u8]) -> NativeResult {
|
||||
builtins_debug!("String.prototype.italics called with {} args", args.len());
|
||||
let s: Vec<u16> = try_string!(this_units(vm, args)).into_owned();
|
||||
NativeResult::Ok(vm.new_string_units_owned(create_html(&s, "i", "", &[])))
|
||||
}
|
||||
|
||||
/// `String.prototype.link(url)`:返回 `<a href="值">串</a>` 形 HTML 片段;
|
||||
/// 属性值经完整 ToString(缺参得 "undefined"),值内双引号替换为 `"`。
|
||||
pub fn string_link<H: VmHost>(vm: &mut H, args: &[u8]) -> NativeResult {
|
||||
builtins_debug!("String.prototype.link called with {} args", args.len());
|
||||
let s: Vec<u16> = try_string!(this_units(vm, args)).into_owned();
|
||||
let val = if args.len() > 1 { vm.reg(args[1]) } else { JsValue::undefined() };
|
||||
let v: Vec<u16> = try_string!(as_units(vm, val)).into_owned();
|
||||
NativeResult::Ok(vm.new_string_units_owned(create_html(&s, "a", "href", &v)))
|
||||
}
|
||||
|
||||
/// `String.prototype.small()`:返回 `<small>串</small>` 形 HTML 片段。
|
||||
pub fn string_small<H: VmHost>(vm: &mut H, args: &[u8]) -> NativeResult {
|
||||
builtins_debug!("String.prototype.small called with {} args", args.len());
|
||||
let s: Vec<u16> = try_string!(this_units(vm, args)).into_owned();
|
||||
NativeResult::Ok(vm.new_string_units_owned(create_html(&s, "small", "", &[])))
|
||||
}
|
||||
|
||||
/// `String.prototype.strike()`:返回 `<strike>串</strike>` 形 HTML 片段。
|
||||
pub fn string_strike<H: VmHost>(vm: &mut H, args: &[u8]) -> NativeResult {
|
||||
builtins_debug!("String.prototype.strike called with {} args", args.len());
|
||||
let s: Vec<u16> = try_string!(this_units(vm, args)).into_owned();
|
||||
NativeResult::Ok(vm.new_string_units_owned(create_html(&s, "strike", "", &[])))
|
||||
}
|
||||
|
||||
/// `String.prototype.sub()`:返回 `<sub>串</sub>` 形 HTML 片段。
|
||||
pub fn string_sub<H: VmHost>(vm: &mut H, args: &[u8]) -> NativeResult {
|
||||
builtins_debug!("String.prototype.sub called with {} args", args.len());
|
||||
let s: Vec<u16> = try_string!(this_units(vm, args)).into_owned();
|
||||
NativeResult::Ok(vm.new_string_units_owned(create_html(&s, "sub", "", &[])))
|
||||
}
|
||||
|
||||
/// `String.prototype.sup()`:返回 `<sup>串</sup>` 形 HTML 片段。
|
||||
pub fn string_sup<H: VmHost>(vm: &mut H, args: &[u8]) -> NativeResult {
|
||||
builtins_debug!("String.prototype.sup called with {} args", args.len());
|
||||
let s: Vec<u16> = try_string!(this_units(vm, args)).into_owned();
|
||||
NativeResult::Ok(vm.new_string_units_owned(create_html(&s, "sup", "", &[])))
|
||||
}
|
||||
|
||||
@@ -281,6 +281,19 @@ impl BuiltinWorld {
|
||||
("lastIndexOf", methods.last_index_of, 1),
|
||||
("isWellFormed", methods.is_well_formed, 0),
|
||||
("toWellFormed", methods.to_well_formed, 0),
|
||||
("anchor", methods.anchor, 1),
|
||||
("big", methods.big, 0),
|
||||
("blink", methods.blink, 0),
|
||||
("bold", methods.bold, 0),
|
||||
("fixed", methods.fixed, 0),
|
||||
("fontcolor", methods.fontcolor, 1),
|
||||
("fontsize", methods.fontsize, 1),
|
||||
("italics", methods.italics, 0),
|
||||
("link", methods.link, 1),
|
||||
("small", methods.small, 0),
|
||||
("strike", methods.strike, 0),
|
||||
("sub", methods.sub, 0),
|
||||
("sup", methods.sup, 0),
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -126,6 +126,19 @@ pub struct StringMethods {
|
||||
pub to_locale_lower_case: *const (),
|
||||
pub to_locale_upper_case: *const (),
|
||||
pub locale_compare: *const (),
|
||||
pub anchor: *const (),
|
||||
pub big: *const (),
|
||||
pub blink: *const (),
|
||||
pub bold: *const (),
|
||||
pub fixed: *const (),
|
||||
pub fontcolor: *const (),
|
||||
pub fontsize: *const (),
|
||||
pub italics: *const (),
|
||||
pub link: *const (),
|
||||
pub small: *const (),
|
||||
pub strike: *const (),
|
||||
pub sub: *const (),
|
||||
pub sup: *const (),
|
||||
}
|
||||
|
||||
/// RegExp 原型方法的 native 函数指针集合。
|
||||
|
||||
@@ -46,6 +46,19 @@ pub fn bind_string(core: &Arc<KernelCore>, session: &KernelSession, global: &mut
|
||||
is_well_formed: oxide_builtins::string::string_is_well_formed::<crate::vm::Vm> as *const (),
|
||||
to_well_formed: oxide_builtins::string::string_to_well_formed::<crate::vm::Vm> as *const (),
|
||||
from_raw: oxide_builtins::string::string_raw::<crate::vm::Vm> as *const (),
|
||||
anchor: oxide_builtins::string::string_anchor::<crate::vm::Vm> as *const (),
|
||||
big: oxide_builtins::string::string_big::<crate::vm::Vm> as *const (),
|
||||
blink: oxide_builtins::string::string_blink::<crate::vm::Vm> as *const (),
|
||||
bold: oxide_builtins::string::string_bold::<crate::vm::Vm> as *const (),
|
||||
fixed: oxide_builtins::string::string_fixed::<crate::vm::Vm> as *const (),
|
||||
fontcolor: oxide_builtins::string::string_fontcolor::<crate::vm::Vm> as *const (),
|
||||
fontsize: oxide_builtins::string::string_fontsize::<crate::vm::Vm> as *const (),
|
||||
italics: oxide_builtins::string::string_italics::<crate::vm::Vm> as *const (),
|
||||
link: oxide_builtins::string::string_link::<crate::vm::Vm> as *const (),
|
||||
small: oxide_builtins::string::string_small::<crate::vm::Vm> as *const (),
|
||||
strike: oxide_builtins::string::string_strike::<crate::vm::Vm> as *const (),
|
||||
sub: oxide_builtins::string::string_sub::<crate::vm::Vm> as *const (),
|
||||
sup: oxide_builtins::string::string_sup::<crate::vm::Vm> as *const (),
|
||||
};
|
||||
session.builtin_world().bind_string_methods(
|
||||
&string_methods,
|
||||
|
||||
Reference in New Issue
Block a user