highlight: extract HTML stuff from highlight into htmlight
[nit.git] / src / web / api_model.nit
index 4f85161..0de4806 100644 (file)
@@ -15,7 +15,7 @@
 module api_model
 
 import web_base
-import highlight
+import htmlight
 import uml
 import model::model_index
 
@@ -26,6 +26,7 @@ redef class APIRouter
                use("/search", new APISearch(config))
                use("/random", new APIRandom(config))
                use("/entity/:id", new APIEntity(config))
+               use("/entity/:id/doc", new APIEntityDoc(config))
                use("/code/:id", new APIEntityCode(config))
                use("/uml/:id", new APIEntityUML(config))
                use("/linearization/:id", new APIEntityLinearization(config))
@@ -69,6 +70,25 @@ class APIList
                return mentities
        end
 
+       # Filter mentities based on the config view filters
+       fun filter_mentities(req: HttpRequest, mentities: Array[MEntity]): Array[MEntity] do
+               var res = new Array[MEntity]
+               for mentity in mentities do
+                       if config.view.filter.accept_mentity(mentity) then res.add mentity
+               end
+               return res
+       end
+
+       # Sort mentities by lexicographic order
+       #
+       # TODO choose order from request
+       fun sort_mentities(req: HttpRequest, mentities: Array[MEntity]): Array[MEntity] do
+               var sorted = mentities.to_a
+               var sorter = new MEntityNameSorter
+               sorter.sort(sorted)
+               return sorted
+       end
+
        # Limit mentities depending on the `n` parameter.
        fun limit_mentities(req: HttpRequest, mentities: Array[MEntity]): Array[MEntity] do
                var n = req.int_arg("n")
@@ -80,6 +100,7 @@ class APIList
 
        redef fun get(req, res) do
                var mentities = list_mentities(req)
+               mentities = sort_mentities(req, mentities)
                mentities = limit_mentities(req, mentities)
                res.json new JsonArray.from(mentities)
        end
@@ -92,13 +113,19 @@ class APISearch
        super APIList
 
        redef fun get(req, res) do
-               var q = req.string_arg("q")
-               if q == null then
-                       res.json new JsonArray
+               var query = req.string_arg("q")
+               if query == null then
+                       res.api_error(400, "Missing search string")
                        return
                end
-               var n = req.int_arg("n")
-               res.json new JsonArray.from(config.view.find(q, n))
+               var page = req.int_arg("p")
+               var limit = req.int_arg("n")
+               var response = new JsonArray.from(search(query, limit))
+               res.json paginate(response, response.length, page, limit)
+       end
+
+       fun search(query: String, limit: nullable Int): Array[MEntity] do
+               return config.view.find(query)
        end
 end
 
@@ -117,8 +144,9 @@ class APIRandom
 
        redef fun get(req, res) do
                var mentities = list_mentities(req)
-               mentities = limit_mentities(req, mentities)
+               mentities = filter_mentities(req, mentities)
                mentities = randomize_mentities(req, mentities)
+               mentities = limit_mentities(req, mentities)
                res.json new JsonArray.from(mentities)
        end
 end
@@ -132,7 +160,27 @@ class APIEntity
        redef fun get(req, res) do
                var mentity = mentity_from_uri(req, res)
                if mentity == null then return
-               res.json mentity.api_json(self)
+               res.raw_json mentity.to_full_json(config.view.mainmodule)
+       end
+end
+
+# Return the full MDoc of a MEntity.
+#
+# Example: `GET /entity/core::Array/doc`
+class APIEntityDoc
+       super APIHandler
+
+       redef fun get(req, res) do
+               var mentity = mentity_from_uri(req, res)
+               if mentity == null then return
+
+               var obj = new JsonObject
+               var mdoc = mentity.mdoc_or_fallback
+               if mdoc != null then
+                       obj["documentation"] = mdoc.html_documentation.write_to_string
+                       obj["location"] = mdoc.location
+               end
+               res.json obj
        end
 end
 
@@ -164,7 +212,7 @@ class APIEntityLinearization
                        return
                end
                var mentities = new JsonArray
-               for e in lin do mentities.add e.full_json
+               for e in lin do mentities.add e
                res.json mentities
        end
 end
@@ -173,25 +221,34 @@ end
 #
 # Example: `GET /defs/core::Array`
 class APIEntityDefs
-       super APIHandler
+       super APIList
 
        redef fun get(req, res) do
                var mentity = mentity_from_uri(req, res)
                if mentity == null then return
-               var arr = new JsonArray
-               if mentity isa MModule then
-                       for mclassdef in mentity.mclassdefs do arr.add mclassdef
+               var mentities = new Array[MEntity]
+               if mentity isa MPackage then
+                       mentities.add_all mentity.collect_mgroups(config.view)
+                       mentities.add_all mentity.collect_mmodules(config.view)
+               else if mentity isa MGroup then
+                       mentities.add_all mentity.collect_mgroups(config.view)
+                       mentities.add_all mentity.collect_mmodules(config.view)
+               else if mentity isa MModule then
+                       mentities.add_all mentity.collect_local_mclassdefs(config.view)
                else if mentity isa MClass then
-                       for mclassdef in mentity.mclassdefs do arr.add mclassdef
+                       mentities.add_all mentity.collect_mclassdefs(config.view)
                else if mentity isa MClassDef then
-                       for mpropdef in mentity.mpropdefs do arr.add mpropdef
+                       mentities.add_all mentity.collect_mpropdefs(config.view)
                else if mentity isa MProperty then
-                       for mpropdef in mentity.mpropdefs do arr.add mpropdef
+                       mentities.add_all mentity.collect_mpropdefs(config.view)
                else
                        res.api_error(404, "No definition list for mentity `{mentity.full_name}`")
                        return
                end
-               res.json arr
+               mentities = filter_mentities(req, mentities)
+               mentities = sort_mentities(req, mentities)
+               mentities = limit_mentities(req, mentities)
+               res.json new JsonArray.from(mentities)
        end
 end
 
@@ -254,8 +311,8 @@ class APIEntityCode
        private fun render_source(mentity: MEntity): nullable HTMLTag do
                var node = config.modelbuilder.mentity2node(mentity)
                if node == null then return null
-               var hl = new HighlightVisitor
-               hl.enter_visit node
+               var hl = new HtmlightVisitor
+               hl.highlight_node node
                return hl.html
        end
 end