use crate::parse::{EmbedRule, Platform}; use crate::Category; pub struct Jsfiddle; impl Platform for Jsfiddle { fn id(&self) -> &'static str { "jsfiddle" } fn name(&self) -> &'static str { "JSFiddle" } fn category(&self) -> Category { Category::Dev } fn domains(&self) -> &'static [&'static str] { &["jsfiddle.net"] } fn embed_rule(&self) -> Option { None } /// fiddle 的嵌入地址是「原路径 + `/embedded//`」,路径本身要原样保留。 /// /// 不能用 `{id}` 模板:`/zalun/Nmud8/`(用户名 + id)与 `/6he52mnr/1/` /// (id + 版本)段数相同、无法靠正则区分谁是谁,而且 `{id}` 会把 `/` 转义成 /// `%2F`。官方文档给的写法就是整段路径后面接 `/embedded/…`。 fn parse(&self, url: &url::Url) -> Option { use crate::parse::platform_resolved; use crate::EmbedKind; let path = url.path().trim_end_matches('/'); let segments: Vec<&str> = path.trim_start_matches('/').split('/').collect(); // 只认 fiddle 路径:`/` 或 `//[/]`。 // `/user/…`、`/settings` 这类是站点页面,不该被塞进 iframe。 const RESERVED: &[&str] = &["user", "settings", "pro", "about", "docs"]; if segments.is_empty() || segments.len() > 3 || segments.iter().any(|segment| segment.is_empty()) || segments .first() .is_some_and(|head| RESERVED.contains(&head.to_ascii_lowercase().as_str())) { return Some(platform_resolved( self, url, EmbedKind::Link, None, crate::Aspect::Auto, )); } Some(platform_resolved( self, url, EmbedKind::Iframe, Some(format!( "https://jsfiddle.net{path}/embedded/js,html,css,result/dark/" )), crate::Aspect::Wide, )) } } pub static PLATFORM: Jsfiddle = Jsfiddle;