sourceafFandocViewer::FandocScheme.fan


** Registers the 'fandoc://' scheme to be viewed in the `Browser`.
** 
** The scheme resolves to a flux `FandocResource`. (Couldn't think of any reason to resolve it to 
** an intermediate object.)
const class FandocScheme : UriScheme {
    override Obj? get(Uri uri, Obj? base) {
        
        // we don't need canonicalize top level docs 
        if (uri.host == null || uri.host.isEmpty)
            return FandocResource(`fandoc://`, base)
        
        // to start off, ensure we have a full and complete uri
        // expand 'fandoc://afFancom' to 'fandoc://afFancom/index' 
        if (uri.basename.isEmpty) {
            if (!uri.isDir)
                uri = uri.plusSlash
            uri = uri.plusName("index")
        }

        // canonicalize 'fandoc://afFancom/../sys/Obj' to 'fandoc://sys/Obj'
        // it's a lot trickier than you'd think!
        scheme  := "fandoc"
        type    := uri.name
        frag    := uri.frag ?: ""
        // working our way backwacks through the path, ignoring the first element, find the first
        // element not equal to ".."
        pod     := uri.path.rw.reverse.find |p, i| {
            p != ".." && i >= 1
        } ?: uri.host

        if (!frag.isEmpty)
            frag = "#$frag"
        
        // reassemble the uri
        uri = `${scheme}://${pod}/${type}${frag}`
        return FandocResource(uri, base)
    }
}