" ++ text ++ ""))
34 | |> replaceAll(out);
35 |
36 | let replaceIds = (ids, out) =>
37 | ids
38 | |> List.map(
39 | ((text, id)) => (
40 | text,
41 | "" ++ text ++ ""
42 | )
43 | )
44 | |> replaceAll(out);
45 |
46 | let replaceListing = (els, text, replace) => {
47 | let hrefs = getNormalizedLinks(els);
48 | let ids = getNormalizedIds(els);
49 | let el = text |> replaceHrefs(hrefs) |> replaceIds(ids) |> replace;
50 | Hljs.highlightBlock(el)
51 | };
52 |
--------------------------------------------------------------------------------
/src/extension/popup.re:
--------------------------------------------------------------------------------
1 | open Core;
2 |
3 | open LocalDom;
4 |
5 | let mapOrElse = (resolve, reject, item) =>
6 | switch (item) {
7 | | Some(res) => resolve(res)
8 | | None => reject()
9 | };
10 |
11 | let getSelection = () =>
12 | Promise.make(
13 | (resolve, reject) =>
14 | Chrome.Tabs.executeScript(
15 | {"code": "window.getSelection().toString()"},
16 | (maybeMaybeArray) => {
17 | maybeMaybeArray
18 | |> Js.Null_undefined.to_opt
19 | |> Js.Option.andThen([@bs](maybeArray) => Js.Array.findi((_, index) => index === 0, maybeArray))
20 | |> Js.Option.andThen([@bs](s) => s == "" ? None : Some(s))
21 | |> mapOrElse(resolve, reject);
22 | }
23 | )
24 | );
25 |
26 | let getLatestInput = () =>
27 | Promise.make(
28 | (resolve, reject) =>
29 | Protocol.Storage.queryLatestInput(
30 | (maybeInput) => maybeInput |> mapOrElse(resolve, reject)
31 | )
32 | );
33 |
34 | let refmt =
35 | (
36 | input,
37 | ~inLang=RefmtShared.UnknownLang,
38 | ~inType=RefmtShared.UnknownType,
39 | ~outLang=RefmtShared.UnknownLang,
40 | cb
41 | ) => {
42 | Protocol.Refmt.send(
43 | input,
44 | ~inLang,
45 | ~inType,
46 | ~outLang,
47 | (error) =>
48 | switch error {
49 | | Result.Error(error) => cb(error, RefmtShared.UnknownLang, RefmtShared.UnknownLang)
50 | | Result.Ok({outText, inLang, outLang}) => cb(outText, inLang, outLang)
51 | }
52 | );
53 | Protocol.Storage.setLatestInput(input)
54 | };
55 |
56 | let onOpen = Protocol.OpenInTab.send;
57 |
58 | Document.addEventListener(
59 | "DOMContentLoaded",
60 | PopupCommon.init(~getSelection, ~getLatestInput, ~onOpen, ~refmt)
61 | );
62 |
--------------------------------------------------------------------------------
/src/extension/common/core.re:
--------------------------------------------------------------------------------
1 | exception Unreachable;
2 |
3 | let noop = (_) => ();
4 |
5 | external id : 'a => 'a = "%identity";
6 |
7 | module MaybeArray = {
8 | type t('a);
9 | /*
10 | let unwrap : t 'a => 'a = [%bs.raw {|
11 | function (maybeArray) {
12 | return Array.isArray(maybeArray)
13 | ? maybeArray[0]
14 | : maybeArray;
15 | }
16 | |}];*/
17 | };
18 |
19 | module Promise = {
20 | type t('a);
21 | [@bs.new] external make : (('a => unit, 'e => unit) => unit) => t('a) = "Promise";
22 | [@bs.send.pipe : t('a)] external then_ : ('a => 'b) => t('b) = "then";
23 | [@bs.send.pipe : t('a)] external and_then : ('a => t('b)) => t('b) = "then";
24 | [@bs.send.pipe : t('a)] external catch : ('e => unit) => t('a) = "";
25 | [@bs.send.pipe : t('a)] external or_ : ('e => 'b) => t('b) = "catch"; /* non-standard name for "overload" */
26 | [@bs.send.pipe : t('a)] external or_else : ('e => t('b)) => t('b) =
27 | "catch"; /* non-standard name for "overload" */
28 | [@bs.val] external all : array(t('a)) => t(array('a)) = "Promise.all";
29 | [@bs.val] external race : array(t('a)) => t('b) = "Promise.race"; /* unsure about what the returned promise will hold */
30 | [@bs.val] external reject : 'e => t('a) = "Promise.reject";
31 | [@bs.val] external resolve : 'a => t('a) = "Promise.resolve";
32 | };
33 |
34 | module History = {
35 | [@bs.val]
36 | external replaceState : (~state: string, ~title: string, ~url: string) => unit =
37 | "window.history.replaceState";
38 | };
39 |
40 | module Util = {
41 | [@bs.val] external btoa : string => string = "window.btoa";
42 | [@bs.val] external atob : string => string = "window.atob";
43 | let classNames = (items) =>
44 | items
45 | |> List.map(((name, flag)) => flag ? name : "")
46 | |> List.filter((s) => s !== "")
47 | |> String.concat(" ");
48 | };
49 |
--------------------------------------------------------------------------------
/src/extension/popup/popupStyles.re:
--------------------------------------------------------------------------------
1 | let popup =
2 | ReactDOMRe.Style.make(
3 | ~display="flex",
4 | ~flex="1",
5 | ~flexDirection="row",
6 | ~justifyContent="space-around",
7 | ~overflow="hidden",
8 | ()
9 | );
10 |
11 | let popupColumn =
12 | ReactDOMRe.Style.make(
13 | ~display="flex",
14 | ~flexDirection="column",
15 | ~paddingBottom="1%",
16 | ~position="relative",
17 | ()
18 | );
19 |
20 | let popupContext =
21 | ReactDOMRe.Style.make(
22 | ~alignItems="center",
23 | ~display="flex",
24 | ~flex="1",
25 | ~fontFamily="sans-serif",
26 | ~fontSize="3vh",
27 | ~justifyContent="space-between",
28 | ~maxHeight="25px",
29 | ~minHeight="16px",
30 | ~paddingBottom="0.5vh",
31 | ~paddingTop="0.5vh",
32 | ~width="100%",
33 | ()
34 | );
35 |
36 | let copyConfirmation =
37 | ReactDOMRe.Style.make(
38 | ~position="absolute",
39 | ~zIndex="10",
40 | ~top="50%",
41 | ~left="50%",
42 | ~transform="translate(-50%,-50%)",
43 | ~padding="4vh 8vh 6vh",
44 | ~display="flex",
45 | ~flexDirection="column",
46 | ~justifyContent="center",
47 | ~alignItems="center",
48 | ~borderRadius="2vh",
49 | ~backgroundColor="rgba(0,0,0,0.8)",
50 | ~color="white",
51 | ~fontFamily="sans-serif",
52 | /*pointerEvents::"none"*/
53 | ()
54 | );
55 |
56 | let contextLink =
57 | ReactDOMRe.Style.make(
58 | ~textDecoration="none",
59 | ~color="rgb(219, 76, 63)",
60 | ~cursor="pointer",
61 | ~fontSize="16px",
62 | ~lineHeight="16px",
63 | ~paddingLeft="1vw",
64 | ()
65 | );
66 |
67 | let contextIcon =
68 | ReactDOMRe.Style.make(
69 | ~paddingLeft="1vw",
70 | ~cursor="pointer", /*fill::"rgb(219, 76, 63)"*/
71 | ~height="16px",
72 | ~width="16px",
73 | ()
74 | );
75 |
76 | let contextTitle = ReactDOMRe.Style.make(~flex="1", ());
77 |
--------------------------------------------------------------------------------
/src/extension/content/convertPage.re:
--------------------------------------------------------------------------------
1 | open LocalDom;
2 |
3 | open Common;
4 |
5 | type saveState = {mutable stylesheets: list(Element.t)};
6 |
7 | let savedState = {stylesheets: [createStylesheet()]};
8 |
9 | let swapStyleSheets = (_) => {
10 | let stylesheets =
11 | getElementsByTagName(None, "link")
12 | |> List.filter((link) => Element.getAttribute(link, "rel") == "stylesheet");
13 | stylesheets |> List.iter(Element.remove);
14 | savedState.stylesheets |> List.iter(Head.appendChild);
15 | savedState.stylesheets = stylesheets
16 | };
17 |
18 | let readjustViewport = () =>
19 | if (! (Location.hash == "")) {
20 | [%bs.raw {| window.location.href = window.location.href |}]
21 | };
22 |
23 | type swapState = {mutable remaining: int};
24 |
25 | let doListing = (mode, state, listing) => {
26 | open Retrieve;
27 | let {els, text, replace} = listing;
28 | Protocol.Refmt.send(
29 | text,
30 | (response) => {
31 | switch response {
32 | | Result.Error(_) => () /* TODO */
33 | | Result.Ok({outText}) => Replace.replaceListing(els, outText, replace)
34 | };
35 | /* we're in an async callback, so keep track of when we're finished by keeping count */
36 | state.remaining = state.remaining - 1;
37 | if (mode == `initial && state.remaining <= 0) {
38 | /* when we're done, the DOM has most likely been shifted,
39 | * so we need to go back to where we're supposed to be */
40 | readjustViewport
41 | ()
42 | }
43 | }
44 | )
45 | };
46 |
47 | let swapSyntax = (mode) => {
48 | let listings = Retrieve.getListings();
49 | let state = {remaining: List.length(listings)};
50 | listings |> List.iter(doListing(mode, state));
51 | if (mode != `initial) {
52 | Overlay.updateSyntaxSwapButton()
53 | }
54 | };
55 |
56 | let toggle = () => {
57 | swapStyleSheets();
58 | Overlay.toggle(swapStyleSheets, swapSyntax);
59 | swapSyntax(`initial)
60 | };
61 |
--------------------------------------------------------------------------------
/webpack.config.js:
--------------------------------------------------------------------------------
1 | const path = require('path');
2 | const webpack = require('webpack');
3 | const GenerateJsonPlugin = require('generate-json-webpack-plugin');
4 | const manifest = require('./src/manifest.json');
5 | const package = require('./package.json');
6 |
7 | manifest.version = package.version;
8 |
9 | const commonModule = {
10 | loaders: [
11 | {
12 | test: /\.(png|jpg|gif|html|css)$/,
13 | loader: 'file-loader?name=[name].[ext]'
14 | }
15 | ],
16 | };
17 |
18 | const Extension = {
19 | name: "Extension",
20 | entry: {
21 | Content: './lib/es6/src/extension/content.js',
22 | ContentLoader: './lib/es6/src/extension/contentLoader.js',
23 | Popup: './lib/es6/src/extension/popup.js',
24 | Background: './lib/es6/src/extension/background.js',
25 | },
26 | output: {
27 | path: path.join(__dirname, '_build/extension/'),
28 | filename: '[name].bundle.js',
29 | },
30 | module: commonModule,
31 | plugins: [
32 | new GenerateJsonPlugin('manifest.json', manifest),
33 | new webpack.DefinePlugin({
34 | '__REASON_VERSION__': '"3.0.0"',
35 | '__OCAML_VERSION__': '"4.02.3"'
36 | }),
37 | ],
38 | node: {
39 | fs: "empty"
40 | },
41 | resolve: {
42 | alias: {
43 | react: path.resolve('./node_modules/react'),
44 | },
45 | },
46 | };
47 |
48 | const Page = {
49 | name: "Page",
50 | entry: {
51 | Popup: './lib/es6/src/extension/page.js',
52 | },
53 | output: {
54 | path: path.join(__dirname, 'docs/'),
55 | filename: '[name].bundle.js',
56 | },
57 | plugins: [
58 | new webpack.DefinePlugin({
59 | '__REASON_VERSION__': '"3.0.0"',
60 | '__OCAML_VERSION__': '"4.02.3"'
61 | }),
62 | ],
63 | module: commonModule,
64 | node: {
65 | fs: "empty"
66 | },
67 | resolve: {
68 | alias: {
69 | react: path.resolve('./node_modules/react'),
70 | },
71 | },
72 | };
73 |
74 | module.exports = [Extension, Page];
75 |
--------------------------------------------------------------------------------
/src/extension/content/inline/inlineListing.re:
--------------------------------------------------------------------------------
1 | open Core;
2 |
3 | external refToElement : Dom.element => LocalDom.Element.t = "%identity";
4 |
5 | type state = {preRef: ref(option(Dom.element))};
6 |
7 | let updatePreRef = (r, {ReasonReact.state}) => state.preRef := Js.Nullable.to_opt(r);
8 |
9 | let component = ReasonReact.reducerComponent("InlineListing");
10 |
11 | let make = (~lang, ~text, ~slideInFrom, ~open_, _) => {
12 | ...component,
13 | initialState: () => {preRef: ref(None)},
14 | didMount: ({state}) => {
15 | switch state.preRef^ {
16 | | Some(r) => Hljs.highlightBlock(refToElement(r))
17 | | None => ()
18 | };
19 | ReasonReact.NoUpdate
20 | },
21 | reducer: ((), _state) => ReasonReact.NoUpdate,
22 | render: (self) => {
23 | let translateY = slideInFrom == "above" ? "-10vh" : "10vh";
24 | let className =
25 | Util.classNames([
26 | ("listing-container", true),
27 | ("ml", lang == RefmtShared.ML),
28 | ("re", lang == RefmtShared.RE)
29 | ]);
30 |
33 | ReactEventRe.Mouse.stopPropagation(e))>
34 |
35 | (ReasonReact.stringToElement(Protocol.stringOfLanguage(lang)))
36 |
37 |
38 |
(ReasonReact.stringToElement(text))
39 |
54 |
55 |
56 |
57 | }
58 | };
59 |
--------------------------------------------------------------------------------
/src/extension/popup/popupCommon.re:
--------------------------------------------------------------------------------
1 | open Core;
2 |
3 | [%bs.raw {|require('../../../../../src/popup.html')|}];
4 |
5 | [%bs.raw {|require('../../../../../src/images/logo19.png')|}];
6 |
7 | [%bs.raw {|require('../../../../../src/images/logo38.png')|}];
8 |
9 | [%bs.raw {|require('../../../../../src/images/logo19_gray.png')|}];
10 |
11 | [%bs.raw {|require('../../../../../src/images/logo38_gray.png')|}];
12 |
13 | [%bs.raw {|require('../../../../../src/images/logo128.png')|}];
14 |
15 | [%bs.raw {|require('../../../../../src/css/codemirror.css')|}];
16 |
17 | [%bs.raw {|require('../../../../../src/css/oceanic-next.css')|}];
18 |
19 | [%bs.raw {|require('codemirror/mode/javascript/javascript')|}];
20 |
21 | [%bs.raw {|require('codemirror/mode/mllike/mllike')|}];
22 |
23 | let rejectedPromise = () => Promise.make((_, reject) => reject());
24 |
25 | let setHash = (hash) => Core.History.replaceState(~state=[%bs.raw "{}"], ~title="", ~url=hash);
26 |
27 | let makeContentHash = (text) => "#" ++ Util.btoa(text);
28 |
29 | let generateShareableLink = (text) => "https://reasonml.github.io/reason-tools/popup.html" ++ text;
30 |
31 | let getInputFromUrl = () => {
32 | let text = LocalDom.Location.hash |> Js.String.sliceToEnd(~from=1) |> Util.atob;
33 | if (text == "") {
34 | Promise.reject()
35 | } else {
36 | Promise.resolve(text)
37 | }
38 | };
39 |
40 | let init =
41 | (
42 | ~getSelection=rejectedPromise,
43 | ~getLatestInput=rejectedPromise,
44 | ~onOpen,
45 | ~refmt:
46 | (
47 | Js.String.t,
48 | ~inLang: Protocol.language=?,
49 | ~inType: Protocol.codeType=?,
50 | ~outLang: Protocol.language=?,
51 | (string, Protocol.language, Protocol.language) => 'a
52 | ) =>
53 | unit,
54 | ()
55 | ) => {
56 | let rec inputChanged = (~inLang=RefmtShared.UnknownLang, ~outLang=RefmtShared.UnknownLang, input) => {
57 | let hash = makeContentHash(input);
58 | let link = generateShareableLink(hash);
59 | setHash(hash);
60 | refmt(
61 | input,
62 | ~inLang,
63 | ~outLang,
64 | (outText, inLang, outLang) => render(input, outText, inLang, outLang, link)
65 | )
66 | }
67 | and render = (inText, outText, inLang, outLang, link) =>
68 | ReactDOMRe.renderToElementWithId(
69 | ,
70 | "app"
71 | );
72 | Promise.(
73 | getInputFromUrl()
74 | |> or_else(getSelection)
75 | |> or_else(getLatestInput)
76 | |> or_((_) => "")
77 | |> then_(inputChanged)
78 | |> ignore
79 | )
80 | };
81 |
--------------------------------------------------------------------------------
/src/extension/content/inline/inlineStyles.re:
--------------------------------------------------------------------------------
1 | let stylesheet = {|
2 | .root-container {
3 | position: fixed;
4 | top: 0;
5 | bottom: 0;
6 | left: 0;
7 | right: 0;
8 | z-index: 65535;
9 | }
10 |
11 | .mask-container {
12 | position: absolute;
13 | box-sizing: border-box;
14 | padding: 5vw;
15 | top: 0;
16 | bottom: 0;
17 | left: 0;
18 | right: 0;
19 | display: flex;
20 | flex-direction: column;
21 | justify-content: center;
22 | background: rgba(0, 0, 0, 0.5);
23 | transition: background 4000ms;
24 | }
25 |
26 | .listing-container,
27 | .error-message-container {
28 | display: flex;
29 |
30 | box-shadow: 5px 5px 7px 0 rgba(0, 0, 0, 0.3);
31 |
32 | font-family: 'Helvetica', 'Open Sans','Helvetica Neue',Helvetica,Arial,sans-serif;
33 | font-size: 14px;
34 | line-height: 20px;
35 | background-color: #2b303b;
36 | color: #c0c5ce;
37 |
38 | font-weight: normal; /* external styles leaking in, why? */
39 |
40 | margin: 0 auto;
41 | margin-bottom: 2vh;
42 | max-width: 1200px;
43 | }
44 |
45 | .error-message-container {
46 | padding: 1em 2em;
47 | color: #dd4b39;
48 | }
49 |
50 | .listing-container > .sidebar {
51 | background: #242831;
52 | padding: 1em;
53 | color: #5F6269;
54 | border-left: 2px solid transparent;
55 | }
56 | .listing-container.re > .sidebar {
57 | border-color: #dd4b39;
58 | }
59 | .listing-container.ml > .sidebar {
60 | border-color: #c87a27;
61 | }
62 |
63 | .listing-container > .main {
64 | width: 100%;
65 | }
66 |
67 | .listing-container > .main > pre {
68 | padding: 1em 2em;
69 | overflow: hidden;
70 | maxHeight: 45vh;
71 | }
72 |
73 | .listing-container > .main > footer {
74 | display: flex;
75 | align-items: center;
76 | justify-content: flex-end;
77 | font-size: .95em;
78 | padding: .5em;
79 | passin-tTop: 0;
80 | }
81 | .listing-container.re > .main > footer {
82 | color: #dd4b39;
83 | fill: #dd4b39;
84 | }
85 | .listing-container.ml > .main > footer {
86 | color: #c87a27;
87 | fill: #c87a27;
88 | }
89 |
90 | .listing-container > .main > footer > a {
91 | color: #51555E;
92 | margin-right: 1.5em;
93 | }
94 |
95 | .listing-container > .main > footer > a.open-button {
96 | fill: #51555E;
97 | margin-right: 1em;
98 | height: 1em;
99 | width: 1em;
100 | margin-top: 1px; /* looks a bit off-center without */
101 | }
102 |
103 | .listing-container > .main > footer > a:hover {
104 | color: #B1B3B7;
105 | fill: #B1B3B7;
106 | cursor: pointer;
107 | }
108 | |};
109 |
--------------------------------------------------------------------------------
/src/extension/content/convert/detect.re:
--------------------------------------------------------------------------------
1 | open Core;
2 |
3 | open LocalDom;
4 |
5 | open Common;
6 |
7 | let hasClassName = (className) => List.length(getElementsByClassName(None, className)) > 0;
8 |
9 | let ocamlishRels = [|"Start", "previous", "next", "Up", "Appendix", "Section", "Subsection"|];
10 |
11 | let hasOcamlRels = () => {
12 | let hits =
13 | getElementsByTagName(None, "link")
14 | |> List.map((link) => ocamlishRels |> Js.Array.includes(Element.getAttribute(link, "rel")))
15 | |> List.filter(id)
16 | |> List.length;
17 | hits >= 3
18 | };
19 |
20 | let hasCommonClassNames = () => {
21 | let hits =
22 | [
23 | "keyword",
24 | "type",
25 | "deprecated",
26 | "mod",
27 | "modt",
28 | "typ",
29 | "spec",
30 | "def",
31 | "ext",
32 | "exn",
33 | "cls",
34 | "include",
35 | "cons",
36 | "paramstable",
37 | "sig_block"
38 | ]
39 | |> List.map(hasClassName)
40 | |> List.filter(id)
41 | |> List.length;
42 | hits >= 3
43 | };
44 |
45 | let hasUniqueClassNames = () =>
46 | ["odoc-doc", "package-index"] |> List.map(hasClassName) |> List.exists(id);
47 |
48 | let mightBeOcamlDoc = () => hasUniqueClassNames() || hasOcamlRels() || hasCommonClassNames();
49 |
50 | let getBlacklist = () => [
51 | "caml.inria.fr/pub/docs/u3-ocaml/ocaml-objects.html", /* #17 */
52 | "asciidoctor.org/docs/user-manual/", /* #40 */
53 | "ocaml.janestreet.com/ocaml-core/latest/doc/core/", /* #46 */
54 | "mwhittaker.github.io/distributed-systems-ocaml/code_MorePipes.html" /* #49 */
55 | ];
56 |
57 | let getWhitelist = () => [
58 | "codebad.com/~hdon/reason-tools-test.html"
59 | ];
60 |
61 | let getSignificantUrl = () => Location.hostname ++ Location.pathname;
62 |
63 | let isWhitelisted = () => getWhitelist() |> List.mem(getSignificantUrl());
64 |
65 | let isBlacklisted = () => getBlacklist() |> List.mem(getSignificantUrl());
66 |
67 | let shouldConvert = () => {
68 | let cached: option(bool) = [%raw "window._rtShouldConvert"] |> Js.Undefined.toOption;
69 | switch cached {
70 | | Some(shouldConvert) => shouldConvert
71 | | None =>
72 | let isWhitelisted = isWhitelisted();
73 | let mightBeOcamlDoc = mightBeOcamlDoc();
74 | let isBlacklisted = isBlacklisted();
75 | let shouldConvert = isWhitelisted || mightBeOcamlDoc && ! isBlacklisted;
76 | /*
77 | Js.log @@ "isWhitelisted: " ^ (string_of_bool isWhitelisted);
78 | Js.log @@ "mightBeOcamlDoc: " ^ (string_of_bool mightBeOcamlDoc);
79 | Js.log @@ "isBlackListed: " ^ (string_of_bool isBlacklisted);
80 | Js.log @@ "shouldConvert: " ^ (string_of_bool shouldConvert);
81 | */
82 | if (shouldConvert) {
83 | ignore([%raw "window._rtShouldConvert = 1"])
84 | } else {
85 | ignore([%raw "window._rtShouldConvert = 0"])
86 | };
87 | shouldConvert
88 | }
89 | };
90 |
--------------------------------------------------------------------------------
/docs/popup.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Reason Tools
5 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
--------------------------------------------------------------------------------
/src/popup.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Reason Tools
5 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
--------------------------------------------------------------------------------
/src/extension/common/chrome.re:
--------------------------------------------------------------------------------
1 | module BrowserAction = {
2 | [@bs.val] external setIcon : Js.t({..}) => unit = "chrome.browserAction.setIcon";
3 | };
4 |
5 | module Extension = {
6 | [@bs.val] external getURL : string => string = "chrome.extension.getURL";
7 | };
8 |
9 | module Runtime = {
10 | [@bs.val] external sendMessage : ('a, 'b) => unit = "chrome.runtime.sendMessage";
11 | [@bs.val]
12 | external addMessageListener : (('a, Js.t({..}), 'b => unit) => unit) => unit =
13 | "chrome.runtime.onMessage.addListener";
14 | };
15 |
16 | module Storage = {
17 | module Local = {
18 | [@bs.val] external get : (string, 'a => unit) => unit = "chrome.storage.local.get";
19 | [@bs.val] external set : Js.t({..}) => unit = "chrome.storage.local.set";
20 | };
21 | [@bs.val]
22 | external addChangeListener :
23 | (
24 | (
25 | Js.Dict.t(
26 | {
27 | .
28 | "newValue": 'a,
29 | "oldValue": 'a
30 | }
31 | ),
32 | string
33 | ) =>
34 | unit
35 | ) =>
36 | unit =
37 | "chrome.storage.onChanged.addListener";
38 | };
39 |
40 | module Commands = {
41 | [@bs.val]
42 | external addListener : (string => unit) => unit = "chrome.commands.onCommand.addListener";
43 | };
44 |
45 | module Tabs = {
46 | type tabId;
47 | /*
48 | type tab = Js.t {.
49 | id: tabId
50 | };
51 | */
52 | [@bs.val] external create : {. "url": string} => unit = "chrome.tabs.create";
53 | [@bs.val] external update : (int, Js.t({..})) => unit = "chrome.tabs.update";
54 | /* TODO: Need MaybeArray to work because Chrome will return an array, but FF supposedly does not */
55 | /*external executeScript : Js.t {. code: string } => (MaybeArray.t (Js.t {..}) => unit) => unit = "chrome.tabs.executeScript" [@@bs.val];*/
56 | [@bs.val]
57 | external executeScript : ({. "code": string}, Js.null_undefined(array(string)) => unit) => unit =
58 | "chrome.tabs.executeScript";
59 | [@bs.val]
60 | external executeScriptFile : ({. "file": string}, unit => unit) => unit =
61 | "chrome.tabs.executeScript";
62 | /* TODO: could use bs.ginore here? */
63 | [@bs.val] external sendMessage : (tabId, 'a, 'b) => unit = "chrome.tabs.sendMessage";
64 | [@bs.val]
65 | external query :
66 | (
67 | Js.t({..}),
68 | array(
69 | {
70 | .
71 | "url": string,
72 | "id": int
73 | }
74 | ) =>
75 | unit
76 | ) =>
77 | unit =
78 | "chrome.tabs.query";
79 | };
80 |
81 | module ContextMenus = {
82 | type id;
83 | /*
84 | type config = Js.t {.
85 | title: string,
86 | context: array string,
87 | onclick: (unit => Tabs.tab => unit)
88 | };
89 | */
90 | [@bs.val] external create : /*config*/ Js.t({..}) => id = "chrome.contextMenus.create";
91 | [@bs.val] external update : (id, /*config*/ Js.t({..})) => unit = "chrome.contextMenus.update";
92 | };
93 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Reason Tools
2 |
3 | Adds [Reason](http://reasonml.github.io/) to the browser.
4 |
5 | ## Getting started
6 |
7 | Directly in the browser: https://reasonml.github.io/reason-tools/popup.html
8 |
9 | Or, browser extensions: [Chrome](https://chrome.google.com/webstore/detail/reason-tools/kmdelnjbembbiodplmhgfjpecibfhadd) | [Firefox](https://addons.mozilla.org/en-US/firefox/addon/reason-tools/)
10 |
11 | 
12 |
13 | When you trigger the extension, it will copy the text you have highlighted and put it into an editor. The text is then translated into the corresponding Reason/OCaml text. Reason Tools will automatically convert between `.re`, `.ml`, `.rei`, and `.mli` text. In browsers that support it (currently just Chrome), a shortcut is added to open the extension with the highlighted text: `Alt+D`.
14 |
15 | 
16 |
17 | ### OCaml Documentation
18 |
19 | Reason Tools tries to detect OCaml documentation pages and automatically convert between Reason and OCaml syntaxes. It provides an escape hatch for use if there is a false positive detection, or if you prefer the default OCamlDoc styles.
20 |
21 | ### Github Integration
22 |
23 | Reason Tools adds a shortcut from interface to implementation files (`.re` <=> `.rei`, `.ml` <=> `.mli`) on Github when it's detected. Triggered by `Alt+I` by default (> v0.0.19).
24 |
25 | ## Contribute
26 |
27 | To get started contributing you can clone and build the extension:
28 |
29 | ```sh
30 | git clone https://github.com/rickyvetter/reason-tools.git
31 | cd reason-tools
32 | npm install # this will take a few minutes
33 | ```
34 |
35 | `npm run build` to build the project. You also have the granular steps `build:self` and `build:js` for faster iteration.
36 |
37 | To load in Chrome, go to `chrome://extensions/` and turn on Developer Mode. From there you should be able to select "Load unpacked extension..." and choose `reason-tools/_build/extension`.
38 |
39 | ### Build Systems
40 |
41 | This project is a bit unconventional in nature (compiling a compiler and a parser/printer to web), so it uses a few build systems currently.
42 |
43 | - A custom `shell.sh` is used to compile Reason and the compiler to JavaScript.
44 | - [Bsb](http://bucklescript.github.io/bucklescript/Manual.html#_build_system_support) is used to build its Reason logic. Nothing special.
45 | - [Webpack](http://webpack.github.io/) is used to bundle the whole js output into a single pack.
46 |
47 | ## Thanks
48 |
49 | The foundation of the project is, without a doubt, [refmt-web](https://github.com/Schmavery/refmt-web). This is an awesome project by @Schmavery which does the same refmt in a web page.
50 |
51 | [reason-web-toplevel](https://github.com/Engil/reason-web-toplevel), by @Engil was also an awesome project where a lot of the work in this project came from.
52 |
53 | Also huge thanks to the [js_of_ocaml](https://github.com/ocsigen/js_of_ocaml) team for building a compiler that pretty effortlessly builds Reason and refmt utils in JS.
54 |
--------------------------------------------------------------------------------
/src/extension/background.re:
--------------------------------------------------------------------------------
1 | open Core;
2 |
3 | module Refmt = {
4 | let refmt = Refmt2.refmt;
5 | let parse =
6 | fun
7 | | Result.Error(error) => Result.Error(error)
8 | | Result.Ok((inLang, outLang, outText)) =>
9 | Result.Ok(
10 | Protocol.Refmt.{
11 | outText,
12 | inLang,
13 | outLang
14 | }
15 | )
16 | ;
17 | };
18 |
19 | Protocol.Refmt.listen(
20 | ({input, inLang, inType, outLang}, respond) =>
21 | Refmt.refmt(input, inLang, inType, outLang) |> Refmt.parse |> respond
22 | );
23 |
24 | Protocol.OpenInTab.listen((text) => Chrome.Tabs.create({"url": "popup.html#" ++ Util.btoa(text)}));
25 |
26 | let loadContentScripts = (tabId, callback) =>
27 | Chrome.Tabs.executeScriptFile(
28 | {"file": "Content.bundle.js"},
29 | () => {
30 | Protocol.NotifyLoaded.send(tabId);
31 | callback()
32 | }
33 | );
34 |
35 | let ensureLoaded = (tabId, callback) =>
36 | Protocol.QueryLoaded.query(
37 | tabId,
38 | (loaded) =>
39 | if (! loaded) {
40 | loadContentScripts(tabId, callback)
41 | } else {
42 | callback()
43 | }
44 | );
45 |
46 | Protocol.LoadScripts.listen((tabId) => loadContentScripts(tabId, noop));
47 |
48 | let refmtSelection = (tabId) => ensureLoaded(tabId, () => Protocol.RefmtSelection.send(tabId));
49 |
50 | let toggleConversion = (tabId) => ensureLoaded(tabId, () => Protocol.ToggleConversion.send(tabId));
51 |
52 | Chrome.ContextMenus.create({
53 | "title": "Refmt",
54 | "contexts": [|"selection"|],
55 | "onclick": (_, tab) => refmtSelection(tab##id)
56 | });
57 |
58 | Chrome.ContextMenus.create({
59 | "title": "Toggle",
60 | "contexts": [|"browser_action", "page"|],
61 | "onclick": (_, tab) => toggleConversion(tab##id)
62 | });
63 |
64 | Chrome.Commands.addListener(
65 | (command) =>
66 | if (command == "toggle_between_interface_and_implementation") {
67 | Chrome.Tabs.query(
68 | {"active": Js.true_, "currentWindow": Js.true_},
69 | (activeTabs) => {
70 | let mapExtension =
71 | fun
72 | | "ml" => "mli"
73 | | "mli" => "ml"
74 | | "re" => "rei"
75 | | "rei" => "re"
76 | | ext => ext;
77 | let convertBetweenInterfaceAndImplementation = (url) =>
78 | switch (Js.Array.pop @@ Js.String.split(".", url)) {
79 | | None => url
80 | | Some(ext) => Js.String.replace("." ++ ext, "." ++ mapExtension(ext), url)
81 | };
82 | let currentTab = activeTabs[0];
83 | let url = currentTab##url;
84 | let newURL = convertBetweenInterfaceAndImplementation(url);
85 | if (newURL != url) {
86 | Chrome.Tabs.update(currentTab##id, {"url": newURL})
87 | }
88 | }
89 | )
90 | }
91 | );
92 |
93 | let enabledIconSet = {"19": "logo19.png", "38": "logo38.png"};
94 |
95 | let disabledIconSet = {"19": "logo19_gray.png", "38": "logo38_gray.png"};
96 |
97 | Protocol.Storage.queryDisabled(
98 | (disabled) => {
99 | let set = (value, ()) => Protocol.Storage.setDisabled(value);
100 | let id =
101 | Chrome.ContextMenus.create({
102 | "title": disabled ? "Enable" : "Disable",
103 | "contexts": [|"browser_action"|],
104 | "onclick": set(! disabled)
105 | });
106 | Chrome.BrowserAction.setIcon({"path": disabled ? disabledIconSet : enabledIconSet});
107 | Protocol.Storage.onDisabledChanged(
108 | (disabled) => {
109 | Chrome.ContextMenus.update(
110 | id,
111 | {"title": disabled ? "Enable" : "Disable", "onclick": set(! disabled)}
112 | );
113 | Chrome.BrowserAction.setIcon({"path": disabled ? disabledIconSet : enabledIconSet})
114 | }
115 | )
116 | }
117 | );
118 |
--------------------------------------------------------------------------------
/src/extension/content/convert/retrieve.re:
--------------------------------------------------------------------------------
1 | open LocalDom;
2 |
3 | open Common;
4 |
5 | type typeTable = {
6 | el: Element.t,
7 | text: string,
8 | remove: unit => unit
9 | };
10 |
11 | type listing = {
12 | els: list(Element.t),
13 | text: string,
14 | replace: string => Element.t
15 | };
16 |
17 | let getTypeTable = (pre) =>
18 | switch (Js.Null.toOption(Element.nextElementSibling(pre))) {
19 | | None => None
20 | | Some(el) =>
21 | if (Js.to_bool(DOMTokenList.contains(Element.classList(el), "typetable"))) {
22 | let text = Element.innerText(el);
23 | switch (Js.Null.toOption(Element.nextSibling(el))) {
24 | | None => Some({el, text, remove: () => Element.remove(el)})
25 | | Some(next) =>
26 | if (Node.nodeType(next) == Node._TEXT_NODE) {
27 | Some({
28 | el,
29 | text: text ++ Node.nodeValue(next),
30 | remove: () => {
31 | Element.remove(el);
32 | Node.removeChild(Node.parentNode(next), next)
33 | }
34 | })
35 | } else {
36 | Some({el, text, remove: () => Element.remove(el)})
37 | }
38 | }
39 | } else {
40 | None
41 | }
42 | };
43 |
44 | let getModuleSignature = (pre) =>
45 | switch (Js.String.endsWith("sig .. end", Element.innerText(pre))) {
46 | | false => None
47 | | true =>
48 | let anchor = LocalDom.Arrayish.toArray(
49 | Element.getElementsByTagName(pre, "a")
50 | )[0];
51 | let anchor = Element.outerHTML(anchor);
52 | let re = [%re "/sig .. end/g"];
53 | let replaced = Js.String.unsafeReplaceBy0(
54 | re,
55 | (_, _, _) => "{ " ++ anchor ++ " }",
56 | Element.innerText(pre)
57 | );
58 | Some({
59 | els: [pre],
60 | text: "",
61 | replace: (_html) => {
62 | Element.setInnerHTML(pre, replaced);
63 | pre
64 | }
65 | })
66 | };
67 |
68 | let getPreListings = () =>
69 | getElementsByTagName(None, "pre")
70 | |> List.map(
71 | (el) =>
72 | switch (getTypeTable(el), getModuleSignature(el)) {
73 | | (Some(typeTable), _) => {
74 | els: [el, typeTable.el],
75 | text: Element.innerText(el) ++ typeTable.text,
76 | replace: (html) => {
77 | Element.setInnerHTML(el, html);
78 | typeTable.remove();
79 | el
80 | }
81 | }
82 | | (_, Some(preListing)) => preListing
83 | | (None, None) => {
84 | els: [el],
85 | text: Element.innerText(el),
86 | replace: (html) => {
87 | Element.setInnerHTML(el, html);
88 | el
89 | }
90 | }
91 | }
92 | );
93 |
94 | let getDefListings = () =>
95 | getElementsByClassName(None, "def")
96 | |> List.map(
97 | (el) => {
98 | els: [el],
99 | text: Element.innerText(el),
100 | replace: (html) => {
101 | Element.setInnerHTML(el, "" ++ html ++ "
");
102 | el
103 | }
104 | }
105 | );
106 |
107 | let getLstListings = () =>
108 | getElementsByClassName(None, "lstlisting")
109 | |> List.map(
110 | (el) => {
111 | els: [el],
112 | text: Element.innerText(el),
113 | replace: (html) => {
114 | let parent = Node.parentNode(el);
115 | Element.setInnerHTML(parent, "" ++ html ++ "
");
116 | parent
117 | }
118 | }
119 | );
120 |
121 | let getCodeListings = () =>
122 | getElementsByTagName(None, "code")
123 | |> List.map(
124 | (el) => {
125 | els: [el],
126 | text: Element.innerText(el),
127 | replace: (html) => {
128 | Element.setInnerHTML(el, html);
129 | el
130 | }
131 | }
132 | );
133 |
134 | let getListings = () =>
135 | [getPreListings, getDefListings, getLstListings, getCodeListings]
136 | |> List.map((f) => f())
137 | |> List.flatten;
138 |
--------------------------------------------------------------------------------
/src/extension/common/protocol.re:
--------------------------------------------------------------------------------
1 | open Common;
2 | open Result;
3 |
4 | type language = RefmtShared.language;
5 |
6 | type codeType = RefmtShared.codeType;
7 |
8 | let stringOfLanguage = RefmtShared.stringOfLanguage;
9 |
10 | let languageOfString = RefmtShared.languageOfString;
11 |
12 | let stringOfType = RefmtShared.stringOfType;
13 |
14 | let stringOfLanguageHuman = (lang: language) =>
15 | switch lang {
16 | | ML => "ML"
17 | | RE => "RE"
18 | | REO => "RE v1"
19 | | UnknownLang => "Unkown"
20 | };
21 |
22 | module Refmt = {
23 | exception DeserializationFail;
24 | type request = {
25 | input: string,
26 | inLang: language,
27 | inType: codeType,
28 | outLang: language
29 | };
30 | [@bs.deriving jsConverter]
31 | type payload = {
32 | outText: string,
33 | inLang: language,
34 | outLang: language
35 | };
36 | type response = result(string, payload);
37 | let responseToJs = x => {
38 | switch (x) {
39 | | Result.Ok(x) => Obj.magic(("Ok", payloadToJs(x)))
40 | | Result.Error(x) => Obj.magic(("Error", x))
41 | };
42 | };
43 | let responseFromJs:Js.Json.t=>response = x => {
44 | switch(Obj.magic(x)) {
45 | | ("Ok", x) => Result.Ok(payloadFromJs(Obj.magic(x)))
46 | | (_, x) => Result.Error(Obj.magic(x))
47 | };
48 | };
49 | /* Bucklescript's variant tags will be erased when serialized, so we have to manually serialize the response
50 | */
51 | let send =
52 | (
53 | text,
54 | ~inLang=RefmtShared.UnknownLang,
55 | ~inType=RefmtShared.UnknownType,
56 | ~outLang=RefmtShared.UnknownLang,
57 | cb:(response)=>unit
58 | ) =>
59 | Message.query(
60 | "refmt:refmt",
61 | {input: text |> normalizeText |> untoplevel, inLang, inType, outLang},
62 | (response) => cb(responseFromJs(response))
63 | );
64 | let listen: ((request, response => unit) => unit) => unit =
65 | (cb) =>
66 | Message.receive(
67 | "refmt:refmt",
68 | (request, _, respond) => cb(request, (r) => {
69 | r |> responseToJs |> respond;
70 | })
71 | );
72 | };
73 |
74 | module OpenInTab = {
75 | let send = (text) => Message.send("background:open", text);
76 | let listen = (callback) => Message.receive("background:open", (text, _, _) => callback(text));
77 | };
78 |
79 | module ToggleConversion = {
80 | let send = (tabId) => Message.sendTab(tabId, "content:toggle", ());
81 | let listen = (callback) => Message.receive("content:toggle", (_, _, _) => callback());
82 | };
83 |
84 | module RefmtSelection = {
85 | let send = (tabId) => Message.sendTab(tabId, "content:refmt-selection", ());
86 | let listen = (callback) => Message.receive("content:refmt-selection", (_, _, _) => callback());
87 | };
88 |
89 | module LoadScripts = {
90 | let send = () => Message.send("background:load-content-scripts", ());
91 | let listen = (callback) =>
92 | Message.receive(
93 | "background:load-content-scripts",
94 | (_, sender, _) => callback(sender##tab##id)
95 | );
96 | };
97 |
98 | module NotifyLoaded = {
99 | let send = (tabId) => Message.sendTab(tabId, "content:notify-loaded", ());
100 | let listen = (callback) => Message.receive("content:notify-loaded", (_, _, _) => callback());
101 | };
102 |
103 | module QueryLoaded = {
104 | let query = (tabId, callback) => Message.queryTab(tabId, "content:query-loaded", (), callback);
105 | let listen = (callback) =>
106 | Message.receive("content:query-loaded", (_, _, respond) => respond(callback()));
107 | };
108 |
109 | module Storage = {
110 | let queryDisabled = (callback: bool => unit) =>
111 | Chrome.Storage.Local.get(
112 | "disabled",
113 | (response) => response##disabled |> Js.Undefined.toOption |> Js.Option.getWithDefault(false) |> callback
114 | );
115 | let setDisabled = (value: bool) => Chrome.Storage.Local.set({"disabled": value});
116 | let onDisabledChanged = (callback: bool => unit) =>
117 | Chrome.Storage.addChangeListener(
118 | (changes, _) =>
119 | switch (Js.Dict.get(changes, "disabled")) {
120 | | Some(change) => callback(change##newValue)
121 | | None => ()
122 | }
123 | );
124 | let queryLatestInput = (callback: option(string) => unit) =>
125 | Chrome.Storage.Local.get(
126 | "latestRefmtString",
127 | (response) => response##latestRefmtString |> Js.Null_undefined.to_opt |> callback
128 | );
129 | let setLatestInput = (value: string) => Chrome.Storage.Local.set({"latestRefmtString": value});
130 | };
131 |
--------------------------------------------------------------------------------
/src/extension/content/overlay.re:
--------------------------------------------------------------------------------
1 | open LocalDom;
2 |
3 | open Common;
4 |
5 | let renderInTheShadows = (renderer) => {
6 | let host = Document.createElement("div");
7 | let shadow = Element.attachShadow(host, {"mode": "closed"});
8 | let remove = () => Body.removeChild(host);
9 | Body.appendChild(host);
10 | /* React must render directly to the shadow root, otherwise onclick handlers won't work */
11 | ReactDOMRe.render(renderer(remove), Element.toReasonJsElement(shadow));
12 | /* Only after React has rendered can we attach the stylesheets, otherwise React will render over them */
13 | let style = Document.createElement("style");
14 | Element.setType(style, "text/css");
15 | Element.setInnerText(style, InlineStyles.stylesheet);
16 | Element.appendChild(shadow, createStylesheet());
17 | Element.appendChild(shadow, style)
18 | };
19 |
20 | let showOverlay = (inLang, inText, outLang, outText) =>
21 | renderInTheShadows(
22 | (remove) =>
23 |
24 | );
25 |
26 | let showError = (message) => renderInTheShadows((remove) => );
27 |
28 | let try_ = (text) =>
29 | Protocol.Refmt.send(
30 | text,
31 | (response) =>
32 | switch response {
33 | | Result.Error(message) => showError(message)
34 | | Result.Ok({outText, inLang, outLang}) => showOverlay(inLang, text, outLang, outText)
35 | }
36 | );
37 |
38 | let ocamlLogo = [%bs.raw {|require('../../../../../src/images/ocamlLogo128.png')|}];
39 |
40 | let reasonLogo = [%bs.raw {|require('../../../../../src/images/logo128.png')|}];
41 |
42 | let addStyleSheet = () => {
43 | let element = Document.createElement("style");
44 | Element.setType(element, "text/css");
45 | Element.setInnerText(
46 | element,
47 | {|
48 | .reason_tools_button.reason_tools_button.reason_tools_button {
49 | position: fixed;
50 | right: 0;
51 | height: 50px;
52 | width: 50px;
53 | background-color: black;
54 | color: white;
55 | font-family: monospace;
56 | display: flex;
57 | justify-content: center;
58 | align-items: center;
59 | font-weight: 900;
60 | opacity: 0.6;
61 | }
62 | .reason_tools_button.reason_tools_button.reason_tools_button:hover {
63 | opacity: 1;
64 | cursor: pointer;
65 | }
66 | .reason_tools_anchor {
67 | color: #cec47f;
68 | }
69 | .reason_tools_anchor:before {
70 | content: '';
71 | float: left;
72 | position: relative;
73 | width: 0;
74 | height: 50px;
75 | margin-top: -50px;
76 | }
77 | .reason_tools_anchor:target:after {
78 | content: '';
79 | position: relative;
80 | width: 4px;
81 | margin-left: -4px;
82 | height: 18px;
83 | float: left;
84 | background-color: #97B98c;
85 | left: -10px;
86 | }
87 | |}
88 | );
89 | Body.appendChild(element)
90 | };
91 |
92 | let updateSyntaxSwapButton = () => {
93 | let element = Document.getElementById("syntax-swap-button");
94 | let style = Element.style(element);
95 | let logo =
96 | Style.backgroundImage(style) |> Js.String.includes(reasonLogo) ? ocamlLogo : reasonLogo;
97 | let url = Chrome.Extension.getURL(logo);
98 | Style.setBackgroundImage(style, {j|url($url)|j})
99 | };
100 |
101 | let addSyntaxSwapButton = (swap) => {
102 | open Element;
103 | let element = Document.createElement("div");
104 | Style.setTop(style(element), "40px");
105 | setId(element, "syntax-swap-button");
106 | setTitle(element, "Swap between OCaml and Reason syntax");
107 | setClassName(element, "reason_tools_button");
108 | setOnClick(element, (_) => swap(`not_initial));
109 | Style.setBackgroundImage(style(element), "url(" ++ Chrome.Extension.getURL(reasonLogo) ++ ")");
110 | Style.setBackgroundSize(style(element), "cover");
111 | Body.appendChild(element)
112 | };
113 |
114 | let addStyleSwapButton = (swap) => {
115 | open Element;
116 | let element = Document.createElement("div");
117 | Style.setTop(style(element), "90px");
118 | setInnerText(element, ">");
119 | setTitle(element, "Swap between custom and original stylesheet");
120 | setClassName(element, "reason_tools_button");
121 | setOnClick(element, swap);
122 | Body.appendChild(element)
123 | };
124 |
125 | let addSwapButtons = (swapStyleSheets, swapSyntax) => {
126 | addStyleSheet();
127 | addSyntaxSwapButton(swapSyntax);
128 | addStyleSwapButton(swapStyleSheets)
129 | };
130 |
131 | let toggle = (swapStyleSheets, swapSyntax) => {
132 | let buttons = Document.getElementsByClassName("reason_tools_button") |> Arrayish.toArray;
133 | if (Array.length(buttons) > 0) {
134 | buttons |> Array.iter(Element.remove)
135 | } else {
136 | addSwapButtons(swapStyleSheets, swapSyntax)
137 | }
138 | };
139 |
--------------------------------------------------------------------------------
/src/extension/common/localDom.re:
--------------------------------------------------------------------------------
1 | module Arrayish = {
2 | type t('a);
3 | [@bs.val] external toArray : t('a) => array('a) = "Array.prototype.slice.call";
4 | };
5 |
6 | module DOMTokenList = {
7 | type t;
8 | [@bs.send] external contains : (t, string) => Js.boolean = "contains";
9 | };
10 |
11 | module Style = {
12 | type t;
13 | [@bs.get] external backgroundImage : t => string = "";
14 | [@bs.set] external setBackgroundImage : (t, string) => unit = "backgroundImage";
15 | [@bs.set] external setBackgroundSize : (t, string) => unit = "backgroundSize";
16 | [@bs.set] external setTop : (t, string) => unit = "top";
17 | };
18 |
19 | module Element = {
20 | type t;
21 | [@bs.get] external classList : t => DOMTokenList.t = "classList";
22 | [@bs.get] external value : Dom.element => string = "value";
23 | [@bs.set] external setClassName : (t, string) => unit = "className";
24 | [@bs.get] external href : t => string = "href";
25 | [@bs.set] external setHref : (t, string) => unit = "href";
26 | [@bs.get] external id : t => string = "id";
27 | [@bs.set] external setId : (t, string) => unit = "id";
28 | [@bs.set] external setInnerHTML : (t, string) => unit = "innerHTML";
29 | [@bs.get] external outerHTML : t => string = "outerHTML";
30 | [@bs.get] external innerText : t => string = "innerText";
31 | [@bs.set] external setInnerText : (t, string) => unit = "innerText";
32 | [@bs.set] external setTitle : (t, string) => unit = "title";
33 | [@bs.get] external nextSibling : t => Js.null(t) = "nextSibling";
34 | [@bs.get] external nextElementSibling : t => Js.null(t) = "nextElementSibling";
35 | [@bs.set] external setRel : (t, string) => unit = "rel";
36 | [@bs.get] external style : t => Style.t = "style";
37 | [@bs.set] external setStyle : (t, string) => unit = "style";
38 | [@bs.set] external setType : (t, string) => unit = "type";
39 | [@bs.set] external setOnClick : (t, Js.t({..}) => unit) => unit = "onclick";
40 | [@bs.send] external appendChild : (t, t) => unit = "";
41 | [@bs.send] external getAttribute : (t, string) => string = "getAttribute";
42 | [@bs.send] external getElementsByClassName : (t, string) => Arrayish.t(t) = "";
43 | [@bs.send] external getElementsByTagName : (t, string) => Arrayish.t(t) = "";
44 | [@bs.send] external remove : t => unit = "remove";
45 | [@bs.send] external querySelectorAll : (t, string) => Arrayish.t(t) = "";
46 | [@bs.send] external attachShadow : (t, Js.t({..})) => t = "";
47 | external toReasonJsElement : t => Dom.element = "%identity";
48 | };
49 |
50 | module Node = {
51 | let _TEXT_NODE = 3;
52 | let _DOCUMENT_POSITION_PRECEDING = 2;
53 | let _DOCUMENT_POSITION_CONTAINS = 8;
54 | [@bs.get] external nodeType : Element.t => int = "";
55 | [@bs.get] external nodeValue : Element.t => string = "";
56 | [@bs.get] external parentNode : Element.t => Element.t = "";
57 | [@bs.send] external cloneNode : Element.t => Element.t = "";
58 | [@bs.send] external compareDocumentPosition : (Element.t, Element.t) => int = "";
59 | [@bs.send]
60 | external insertBefore : (~target: Element.t, ~new_: Element.t, ~ref_: Element.t) => unit = "";
61 | [@bs.send] external removeChild : (Element.t, Element.t) => unit = "";
62 | };
63 |
64 | module Document = {
65 | type t;
66 | [@bs.val]
67 | external addEventListener : (string, unit => unit) => unit = "document.addEventListener";
68 | [@bs.val] external createElement : string => Element.t = "document.createElement";
69 | [@bs.val]
70 | external getElementsByClassName : string => Arrayish.t(Element.t) =
71 | "document.getElementsByClassName";
72 | [@bs.val] external getElementById : string => Element.t = "document.getElementById";
73 | [@bs.val]
74 | external getElementsByTagName : string => Arrayish.t(Element.t) =
75 | "document.getElementsByTagName";
76 | };
77 |
78 | module Location = {
79 | [@bs.val] external hash : string = "window.location.hash";
80 | [@bs.val] external hostname : string = "window.location.hostname";
81 | [@bs.val] external pathname : string = "window.location.pathname";
82 | [@bs.val] external reload : Js.boolean => unit = "window.location.reload";
83 | };
84 |
85 | module Body = {
86 | [@bs.val] external outerHTML : string = "document.body.outerHTML";
87 | [@bs.val] external appendChild : Element.t => unit = "document.body.appendChild";
88 | [@bs.val] external removeChild : Element.t => unit = "document.body.removeChild";
89 | };
90 |
91 | module Head = {
92 | [@bs.val] external appendChild : Element.t => unit = "document.head.appendChild";
93 | };
94 |
95 | module Selection = {
96 | type t;
97 | [@bs.get] external anchorNode : t => Element.t = "";
98 | [@bs.get] external focusNode : t => Element.t = "";
99 | [@bs.send] external toString : t => string = "";
100 | [@bs.send] external removeAllRanges : t => unit = "";
101 | };
102 |
103 | module Window = {
104 | [@bs.val] external getSelection : unit => Selection.t = "window.getSelection";
105 | };
106 |
--------------------------------------------------------------------------------
/src/extension/popup/popupWindow.re:
--------------------------------------------------------------------------------
1 | type action =
2 | | LinkCopyConfirmation
3 | | TextCopyConfirmation
4 | | RemoveCopyConfirmation
5 | | InLanguageChange(RefmtShared.language)
6 | | OutLanguageChange(RefmtShared.language);
7 |
8 | let select = (name, onChange, language, lang) =>
9 | ;
28 |
29 | type state = {
30 | copyConfirmation: string,
31 | inLanguage: Protocol.language,
32 | outLanguage: Protocol.language,
33 | dialogKillTimer: ref(option(Js.Global.timeoutId))
34 | };
35 |
36 | let resetTimer = ({ReasonReact.state, reduce}) => {
37 | switch state.dialogKillTimer^ {
38 | | None => ()
39 | | Some(timer) => Js.Global.clearTimeout(timer)
40 | };
41 | state.dialogKillTimer := Some(Js.Global.setTimeout(reduce(() => RemoveCopyConfirmation), 2500))
42 | };
43 |
44 | let component = ReasonReact.reducerComponent("PopupWindow");
45 |
46 | let make =
47 | (
48 | ~inText,
49 | ~inLang,
50 | ~outText,
51 | ~outLang,
52 | ~link,
53 | ~onOpen,
54 | ~onInputChanged:
55 | (~inLang: Protocol.language=?, ~outLang: Protocol.language=?, string) => unit,
56 | _
57 | ) => {
58 | ...component,
59 | reducer: (action, state) =>
60 | switch action {
61 | | LinkCopyConfirmation =>
62 | ReasonReact.UpdateWithSideEffects(
63 | {...state, copyConfirmation: "Link copied to clipboard"},
64 | resetTimer
65 | )
66 | | TextCopyConfirmation =>
67 | ReasonReact.UpdateWithSideEffects(
68 | {...state, copyConfirmation: "Text copied to clipboard"},
69 | resetTimer
70 | )
71 | | RemoveCopyConfirmation => ReasonReact.Update({...state, copyConfirmation: ""})
72 | | InLanguageChange(lang) =>
73 | ReasonReact.UpdateWithSideEffects(
74 | {...state, inLanguage: lang},
75 | ((self) => onInputChanged(~inLang=lang, ~outLang=self.state.outLanguage, inText))
76 | )
77 | | OutLanguageChange(lang) =>
78 | ReasonReact.UpdateWithSideEffects(
79 | {...state, outLanguage: lang},
80 | ((self) => onInputChanged(~inLang=self.state.inLanguage, ~outLang=lang, inText))
81 | )
82 | },
83 | initialState: () => {
84 | copyConfirmation: "",
85 | inLanguage: RefmtShared.UnknownLang,
86 | outLanguage: RefmtShared.UnknownLang,
87 | dialogKillTimer: ref(None)
88 | },
89 | render: ({state, reduce, handle}) => {
90 | Js.log(inText);
91 | let inLanguageChange = (event) => {
92 | let lang =
93 | event
94 | |> ReactEventRe.Synthetic.target
95 | |> LocalDom.Element.value
96 | |> Protocol.languageOfString;
97 | InLanguageChange(lang)
98 | };
99 | let outLanguageChange = (event) => {
100 | let lang =
101 | event
102 | |> ReactEventRe.Synthetic.target
103 | |> LocalDom.Element.value
104 | |> Protocol.languageOfString;
105 | OutLanguageChange(lang)
106 | };
107 | let handleInputChange = (input, {ReasonReact.state}) =>
108 | onInputChanged(~inLang=state.inLanguage, ~outLang=state.outLanguage, input);
109 |
110 |
111 |
112 |
116 |
117 | CodeMirror.execCommand(editor, "selectAll")}
122 | onChange=(handle(handleInputChange))
123 | />
124 |
125 |
126 |
127 |
131 | LinkCopyConfirmation))
136 | />
137 | TextCopyConfirmation))
141 | />
142 | onOpen(inText)) />
143 |
144 |
145 |
150 |
151 |
152 | }
153 | };
154 |
--------------------------------------------------------------------------------
/src/images/ocamlLogo.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
117 |
--------------------------------------------------------------------------------
/docs/codemirror.css:
--------------------------------------------------------------------------------
1 | /* BASICS */
2 |
3 | .CodeMirror {
4 | /* Set height, width, borders, and global font properties here */
5 | font-family: monospace;
6 | height: 300px;
7 | color: black;
8 | }
9 |
10 | /* PADDING */
11 |
12 | .CodeMirror-lines {
13 | padding: 4px 0; /* Vertical padding around content */
14 | }
15 | .CodeMirror pre {
16 | padding: 0 4px; /* Horizontal padding of content */
17 | }
18 |
19 | .CodeMirror-scrollbar-filler, .CodeMirror-gutter-filler {
20 | background-color: white; /* The little square between H and V scrollbars */
21 | }
22 |
23 | /* GUTTER */
24 |
25 | .CodeMirror-gutters {
26 | border-right: 1px solid #ddd;
27 | background-color: #f7f7f7;
28 | white-space: nowrap;
29 | }
30 | .CodeMirror-linenumbers {}
31 | .CodeMirror-linenumber {
32 | padding: 0 3px 0 5px;
33 | min-width: 20px;
34 | text-align: right;
35 | color: #999;
36 | white-space: nowrap;
37 | }
38 |
39 | .CodeMirror-guttermarker { color: black; }
40 | .CodeMirror-guttermarker-subtle { color: #999; }
41 |
42 | /* CURSOR */
43 |
44 | .CodeMirror-cursor {
45 | border-left: 1px solid black;
46 | border-right: none;
47 | width: 0;
48 | }
49 | /* Shown when moving in bi-directional text */
50 | .CodeMirror div.CodeMirror-secondarycursor {
51 | border-left: 1px solid silver;
52 | }
53 | .cm-fat-cursor .CodeMirror-cursor {
54 | width: auto;
55 | border: 0 !important;
56 | background: #7e7;
57 | }
58 | .cm-fat-cursor div.CodeMirror-cursors {
59 | z-index: 1;
60 | }
61 |
62 | .cm-animate-fat-cursor {
63 | width: auto;
64 | border: 0;
65 | -webkit-animation: blink 1.06s steps(1) infinite;
66 | -moz-animation: blink 1.06s steps(1) infinite;
67 | animation: blink 1.06s steps(1) infinite;
68 | background-color: #7e7;
69 | }
70 | @-moz-keyframes blink {
71 | 0% {}
72 | 50% { background-color: transparent; }
73 | 100% {}
74 | }
75 | @-webkit-keyframes blink {
76 | 0% {}
77 | 50% { background-color: transparent; }
78 | 100% {}
79 | }
80 | @keyframes blink {
81 | 0% {}
82 | 50% { background-color: transparent; }
83 | 100% {}
84 | }
85 |
86 | /* Can style cursor different in overwrite (non-insert) mode */
87 | .CodeMirror-overwrite .CodeMirror-cursor {}
88 |
89 | .cm-tab { display: inline-block; text-decoration: inherit; }
90 |
91 | .CodeMirror-rulers {
92 | position: absolute;
93 | left: 0; right: 0; top: -50px; bottom: -20px;
94 | overflow: hidden;
95 | }
96 | .CodeMirror-ruler {
97 | border-left: 1px solid #ccc;
98 | top: 0; bottom: 0;
99 | position: absolute;
100 | }
101 |
102 | /* DEFAULT THEME */
103 |
104 | .cm-s-default .cm-header {color: blue;}
105 | .cm-s-default .cm-quote {color: #090;}
106 | .cm-negative {color: #d44;}
107 | .cm-positive {color: #292;}
108 | .cm-header, .cm-strong {font-weight: bold;}
109 | .cm-em {font-style: italic;}
110 | .cm-link {text-decoration: underline;}
111 | .cm-strikethrough {text-decoration: line-through;}
112 |
113 | .cm-s-default .cm-keyword {color: #708;}
114 | .cm-s-default .cm-atom {color: #219;}
115 | .cm-s-default .cm-number {color: #164;}
116 | .cm-s-default .cm-def {color: #00f;}
117 | .cm-s-default .cm-variable,
118 | .cm-s-default .cm-punctuation,
119 | .cm-s-default .cm-property,
120 | .cm-s-default .cm-operator {}
121 | .cm-s-default .cm-variable-2 {color: #05a;}
122 | .cm-s-default .cm-variable-3 {color: #085;}
123 | .cm-s-default .cm-comment {color: #a50;}
124 | .cm-s-default .cm-string {color: #a11;}
125 | .cm-s-default .cm-string-2 {color: #f50;}
126 | .cm-s-default .cm-meta {color: #555;}
127 | .cm-s-default .cm-qualifier {color: #555;}
128 | .cm-s-default .cm-builtin {color: #30a;}
129 | .cm-s-default .cm-bracket {color: #997;}
130 | .cm-s-default .cm-tag {color: #170;}
131 | .cm-s-default .cm-attribute {color: #00c;}
132 | .cm-s-default .cm-hr {color: #999;}
133 | .cm-s-default .cm-link {color: #00c;}
134 |
135 | .cm-s-default .cm-error {color: #f00;}
136 | .cm-invalidchar {color: #f00;}
137 |
138 | .CodeMirror-composing { border-bottom: 2px solid; }
139 |
140 | /* Default styles for common addons */
141 |
142 | div.CodeMirror span.CodeMirror-matchingbracket {color: #0f0;}
143 | div.CodeMirror span.CodeMirror-nonmatchingbracket {color: #f22;}
144 | .CodeMirror-matchingtag { background: rgba(255, 150, 0, .3); }
145 | .CodeMirror-activeline-background {background: #e8f2ff;}
146 |
147 | /* STOP */
148 |
149 | /* The rest of this file contains styles related to the mechanics of
150 | the editor. You probably shouldn't touch them. */
151 |
152 | .CodeMirror {
153 | position: relative;
154 | overflow: hidden;
155 | background: white;
156 | }
157 |
158 | .CodeMirror-scroll {
159 | overflow: scroll !important; /* Things will break if this is overridden */
160 | /* 30px is the magic margin used to hide the element's real scrollbars */
161 | /* See overflow: hidden in .CodeMirror */
162 | margin-bottom: -30px; margin-right: -30px;
163 | padding-bottom: 30px;
164 | height: 100%;
165 | outline: none; /* Prevent dragging from highlighting the element */
166 | position: relative;
167 | }
168 | .CodeMirror-sizer {
169 | position: relative;
170 | border-right: 30px solid transparent;
171 | }
172 |
173 | /* The fake, visible scrollbars. Used to force redraw during scrolling
174 | before actual scrolling happens, thus preventing shaking and
175 | flickering artifacts. */
176 | .CodeMirror-vscrollbar, .CodeMirror-hscrollbar, .CodeMirror-scrollbar-filler, .CodeMirror-gutter-filler {
177 | position: absolute;
178 | z-index: 6;
179 | display: none;
180 | }
181 | .CodeMirror-vscrollbar {
182 | right: 0; top: 0;
183 | overflow-x: hidden;
184 | overflow-y: scroll;
185 | }
186 | .CodeMirror-hscrollbar {
187 | bottom: 0; left: 0;
188 | overflow-y: hidden;
189 | overflow-x: scroll;
190 | }
191 | .CodeMirror-scrollbar-filler {
192 | right: 0; bottom: 0;
193 | }
194 | .CodeMirror-gutter-filler {
195 | left: 0; bottom: 0;
196 | }
197 |
198 | .CodeMirror-gutters {
199 | position: absolute; left: 0; top: 0;
200 | min-height: 100%;
201 | z-index: 3;
202 | }
203 | .CodeMirror-gutter {
204 | white-space: normal;
205 | height: 100%;
206 | display: inline-block;
207 | vertical-align: top;
208 | margin-bottom: -30px;
209 | }
210 | .CodeMirror-gutter-wrapper {
211 | position: absolute;
212 | z-index: 4;
213 | background: none !important;
214 | border: none !important;
215 | }
216 | .CodeMirror-gutter-background {
217 | position: absolute;
218 | top: 0; bottom: 0;
219 | z-index: 4;
220 | }
221 | .CodeMirror-gutter-elt {
222 | position: absolute;
223 | cursor: default;
224 | z-index: 4;
225 | }
226 | .CodeMirror-gutter-wrapper {
227 | -webkit-user-select: none;
228 | -moz-user-select: none;
229 | user-select: none;
230 | }
231 |
232 | .CodeMirror-lines {
233 | cursor: text;
234 | min-height: 1px; /* prevents collapsing before first draw */
235 | }
236 | .CodeMirror pre {
237 | /* Reset some styles that the rest of the page might have set */
238 | -moz-border-radius: 0; -webkit-border-radius: 0; border-radius: 0;
239 | border-width: 0;
240 | background: transparent;
241 | font-family: inherit;
242 | font-size: inherit;
243 | margin: 0;
244 | white-space: pre;
245 | word-wrap: normal;
246 | line-height: inherit;
247 | color: inherit;
248 | z-index: 2;
249 | position: relative;
250 | overflow: visible;
251 | -webkit-tap-highlight-color: transparent;
252 | -webkit-font-variant-ligatures: none;
253 | font-variant-ligatures: none;
254 | }
255 | .CodeMirror-wrap pre {
256 | word-wrap: break-word;
257 | white-space: pre-wrap;
258 | word-break: normal;
259 | }
260 |
261 | .CodeMirror-linebackground {
262 | position: absolute;
263 | left: 0; right: 0; top: 0; bottom: 0;
264 | z-index: 0;
265 | }
266 |
267 | .CodeMirror-linewidget {
268 | position: relative;
269 | z-index: 2;
270 | overflow: auto;
271 | }
272 |
273 | .CodeMirror-widget {}
274 |
275 | .CodeMirror-code {
276 | outline: none;
277 | }
278 |
279 | /* Force content-box sizing for the elements where we expect it */
280 | .CodeMirror-scroll,
281 | .CodeMirror-sizer,
282 | .CodeMirror-gutter,
283 | .CodeMirror-gutters,
284 | .CodeMirror-linenumber {
285 | -moz-box-sizing: content-box;
286 | box-sizing: content-box;
287 | }
288 |
289 | .CodeMirror-measure {
290 | position: absolute;
291 | width: 100%;
292 | height: 0;
293 | overflow: hidden;
294 | visibility: hidden;
295 | }
296 |
297 | .CodeMirror-cursor {
298 | position: absolute;
299 | pointer-events: none;
300 | }
301 | .CodeMirror-measure pre { position: static; }
302 |
303 | div.CodeMirror-cursors {
304 | visibility: hidden;
305 | position: relative;
306 | z-index: 3;
307 | }
308 | div.CodeMirror-dragcursors {
309 | visibility: visible;
310 | }
311 |
312 | .CodeMirror-focused div.CodeMirror-cursors {
313 | visibility: visible;
314 | }
315 |
316 | .CodeMirror-selected { background: #d9d9d9; }
317 | .CodeMirror-focused .CodeMirror-selected { background: #d7d4f0; }
318 | .CodeMirror-crosshair { cursor: crosshair; }
319 | .CodeMirror-line::selection, .CodeMirror-line > span::selection, .CodeMirror-line > span > span::selection { background: #d7d4f0; }
320 | .CodeMirror-line::-moz-selection, .CodeMirror-line > span::-moz-selection, .CodeMirror-line > span > span::-moz-selection { background: #d7d4f0; }
321 |
322 | .cm-searching {
323 | background: #ffa;
324 | background: rgba(255, 255, 0, .4);
325 | }
326 |
327 | /* Used to force a border model for a node */
328 | .cm-force-border { padding-right: .1px; }
329 |
330 | @media print {
331 | /* Hide the cursor when printing */
332 | .CodeMirror div.CodeMirror-cursors {
333 | visibility: hidden;
334 | }
335 | }
336 |
337 | /* See issue #2901 */
338 | .cm-tab-wrap-hack:after { content: ''; }
339 |
340 | /* Help users use markselection to safely style text background */
341 | span.CodeMirror-selectedtext { background: none; }
342 |
--------------------------------------------------------------------------------
/src/css/codemirror.css:
--------------------------------------------------------------------------------
1 | /* BASICS */
2 |
3 | .CodeMirror {
4 | /* Set height, width, borders, and global font properties here */
5 | font-family: monospace;
6 | height: 300px;
7 | color: black;
8 | }
9 |
10 | /* PADDING */
11 |
12 | .CodeMirror-lines {
13 | padding: 4px 0; /* Vertical padding around content */
14 | }
15 | .CodeMirror pre {
16 | padding: 0 4px; /* Horizontal padding of content */
17 | }
18 |
19 | .CodeMirror-scrollbar-filler, .CodeMirror-gutter-filler {
20 | background-color: white; /* The little square between H and V scrollbars */
21 | }
22 |
23 | /* GUTTER */
24 |
25 | .CodeMirror-gutters {
26 | border-right: 1px solid #ddd;
27 | background-color: #f7f7f7;
28 | white-space: nowrap;
29 | }
30 | .CodeMirror-linenumbers {}
31 | .CodeMirror-linenumber {
32 | padding: 0 3px 0 5px;
33 | min-width: 20px;
34 | text-align: right;
35 | color: #999;
36 | white-space: nowrap;
37 | }
38 |
39 | .CodeMirror-guttermarker { color: black; }
40 | .CodeMirror-guttermarker-subtle { color: #999; }
41 |
42 | /* CURSOR */
43 |
44 | .CodeMirror-cursor {
45 | border-left: 1px solid black;
46 | border-right: none;
47 | width: 0;
48 | }
49 | /* Shown when moving in bi-directional text */
50 | .CodeMirror div.CodeMirror-secondarycursor {
51 | border-left: 1px solid silver;
52 | }
53 | .cm-fat-cursor .CodeMirror-cursor {
54 | width: auto;
55 | border: 0 !important;
56 | background: #7e7;
57 | }
58 | .cm-fat-cursor div.CodeMirror-cursors {
59 | z-index: 1;
60 | }
61 |
62 | .cm-animate-fat-cursor {
63 | width: auto;
64 | border: 0;
65 | -webkit-animation: blink 1.06s steps(1) infinite;
66 | -moz-animation: blink 1.06s steps(1) infinite;
67 | animation: blink 1.06s steps(1) infinite;
68 | background-color: #7e7;
69 | }
70 | @-moz-keyframes blink {
71 | 0% {}
72 | 50% { background-color: transparent; }
73 | 100% {}
74 | }
75 | @-webkit-keyframes blink {
76 | 0% {}
77 | 50% { background-color: transparent; }
78 | 100% {}
79 | }
80 | @keyframes blink {
81 | 0% {}
82 | 50% { background-color: transparent; }
83 | 100% {}
84 | }
85 |
86 | /* Can style cursor different in overwrite (non-insert) mode */
87 | .CodeMirror-overwrite .CodeMirror-cursor {}
88 |
89 | .cm-tab { display: inline-block; text-decoration: inherit; }
90 |
91 | .CodeMirror-rulers {
92 | position: absolute;
93 | left: 0; right: 0; top: -50px; bottom: -20px;
94 | overflow: hidden;
95 | }
96 | .CodeMirror-ruler {
97 | border-left: 1px solid #ccc;
98 | top: 0; bottom: 0;
99 | position: absolute;
100 | }
101 |
102 | /* DEFAULT THEME */
103 |
104 | .cm-s-default .cm-header {color: blue;}
105 | .cm-s-default .cm-quote {color: #090;}
106 | .cm-negative {color: #d44;}
107 | .cm-positive {color: #292;}
108 | .cm-header, .cm-strong {font-weight: bold;}
109 | .cm-em {font-style: italic;}
110 | .cm-link {text-decoration: underline;}
111 | .cm-strikethrough {text-decoration: line-through;}
112 |
113 | .cm-s-default .cm-keyword {color: #708;}
114 | .cm-s-default .cm-atom {color: #219;}
115 | .cm-s-default .cm-number {color: #164;}
116 | .cm-s-default .cm-def {color: #00f;}
117 | .cm-s-default .cm-variable,
118 | .cm-s-default .cm-punctuation,
119 | .cm-s-default .cm-property,
120 | .cm-s-default .cm-operator {}
121 | .cm-s-default .cm-variable-2 {color: #05a;}
122 | .cm-s-default .cm-variable-3 {color: #085;}
123 | .cm-s-default .cm-comment {color: #a50;}
124 | .cm-s-default .cm-string {color: #a11;}
125 | .cm-s-default .cm-string-2 {color: #f50;}
126 | .cm-s-default .cm-meta {color: #555;}
127 | .cm-s-default .cm-qualifier {color: #555;}
128 | .cm-s-default .cm-builtin {color: #30a;}
129 | .cm-s-default .cm-bracket {color: #997;}
130 | .cm-s-default .cm-tag {color: #170;}
131 | .cm-s-default .cm-attribute {color: #00c;}
132 | .cm-s-default .cm-hr {color: #999;}
133 | .cm-s-default .cm-link {color: #00c;}
134 |
135 | .cm-s-default .cm-error {color: #f00;}
136 | .cm-invalidchar {color: #f00;}
137 |
138 | .CodeMirror-composing { border-bottom: 2px solid; }
139 |
140 | /* Default styles for common addons */
141 |
142 | div.CodeMirror span.CodeMirror-matchingbracket {color: #0f0;}
143 | div.CodeMirror span.CodeMirror-nonmatchingbracket {color: #f22;}
144 | .CodeMirror-matchingtag { background: rgba(255, 150, 0, .3); }
145 | .CodeMirror-activeline-background {background: #e8f2ff;}
146 |
147 | /* STOP */
148 |
149 | /* The rest of this file contains styles related to the mechanics of
150 | the editor. You probably shouldn't touch them. */
151 |
152 | .CodeMirror {
153 | position: relative;
154 | overflow: hidden;
155 | background: white;
156 | }
157 |
158 | .CodeMirror-scroll {
159 | overflow: scroll !important; /* Things will break if this is overridden */
160 | /* 30px is the magic margin used to hide the element's real scrollbars */
161 | /* See overflow: hidden in .CodeMirror */
162 | margin-bottom: -30px; margin-right: -30px;
163 | padding-bottom: 30px;
164 | height: 100%;
165 | outline: none; /* Prevent dragging from highlighting the element */
166 | position: relative;
167 | }
168 | .CodeMirror-sizer {
169 | position: relative;
170 | border-right: 30px solid transparent;
171 | }
172 |
173 | /* The fake, visible scrollbars. Used to force redraw during scrolling
174 | before actual scrolling happens, thus preventing shaking and
175 | flickering artifacts. */
176 | .CodeMirror-vscrollbar, .CodeMirror-hscrollbar, .CodeMirror-scrollbar-filler, .CodeMirror-gutter-filler {
177 | position: absolute;
178 | z-index: 6;
179 | display: none;
180 | }
181 | .CodeMirror-vscrollbar {
182 | right: 0; top: 0;
183 | overflow-x: hidden;
184 | overflow-y: scroll;
185 | }
186 | .CodeMirror-hscrollbar {
187 | bottom: 0; left: 0;
188 | overflow-y: hidden;
189 | overflow-x: scroll;
190 | }
191 | .CodeMirror-scrollbar-filler {
192 | right: 0; bottom: 0;
193 | }
194 | .CodeMirror-gutter-filler {
195 | left: 0; bottom: 0;
196 | }
197 |
198 | .CodeMirror-gutters {
199 | position: absolute; left: 0; top: 0;
200 | min-height: 100%;
201 | z-index: 3;
202 | }
203 | .CodeMirror-gutter {
204 | white-space: normal;
205 | height: 100%;
206 | display: inline-block;
207 | vertical-align: top;
208 | margin-bottom: -30px;
209 | }
210 | .CodeMirror-gutter-wrapper {
211 | position: absolute;
212 | z-index: 4;
213 | background: none !important;
214 | border: none !important;
215 | }
216 | .CodeMirror-gutter-background {
217 | position: absolute;
218 | top: 0; bottom: 0;
219 | z-index: 4;
220 | }
221 | .CodeMirror-gutter-elt {
222 | position: absolute;
223 | cursor: default;
224 | z-index: 4;
225 | }
226 | .CodeMirror-gutter-wrapper {
227 | -webkit-user-select: none;
228 | -moz-user-select: none;
229 | user-select: none;
230 | }
231 |
232 | .CodeMirror-lines {
233 | cursor: text;
234 | min-height: 1px; /* prevents collapsing before first draw */
235 | }
236 | .CodeMirror pre {
237 | /* Reset some styles that the rest of the page might have set */
238 | -moz-border-radius: 0; -webkit-border-radius: 0; border-radius: 0;
239 | border-width: 0;
240 | background: transparent;
241 | font-family: inherit;
242 | font-size: inherit;
243 | margin: 0;
244 | white-space: pre;
245 | word-wrap: normal;
246 | line-height: inherit;
247 | color: inherit;
248 | z-index: 2;
249 | position: relative;
250 | overflow: visible;
251 | -webkit-tap-highlight-color: transparent;
252 | -webkit-font-variant-ligatures: none;
253 | font-variant-ligatures: none;
254 | }
255 | .CodeMirror-wrap pre {
256 | word-wrap: break-word;
257 | white-space: pre-wrap;
258 | word-break: normal;
259 | }
260 |
261 | .CodeMirror-linebackground {
262 | position: absolute;
263 | left: 0; right: 0; top: 0; bottom: 0;
264 | z-index: 0;
265 | }
266 |
267 | .CodeMirror-linewidget {
268 | position: relative;
269 | z-index: 2;
270 | overflow: auto;
271 | }
272 |
273 | .CodeMirror-widget {}
274 |
275 | .CodeMirror-code {
276 | outline: none;
277 | }
278 |
279 | /* Force content-box sizing for the elements where we expect it */
280 | .CodeMirror-scroll,
281 | .CodeMirror-sizer,
282 | .CodeMirror-gutter,
283 | .CodeMirror-gutters,
284 | .CodeMirror-linenumber {
285 | -moz-box-sizing: content-box;
286 | box-sizing: content-box;
287 | }
288 |
289 | .CodeMirror-measure {
290 | position: absolute;
291 | width: 100%;
292 | height: 0;
293 | overflow: hidden;
294 | visibility: hidden;
295 | }
296 |
297 | .CodeMirror-cursor {
298 | position: absolute;
299 | pointer-events: none;
300 | }
301 | .CodeMirror-measure pre { position: static; }
302 |
303 | div.CodeMirror-cursors {
304 | visibility: hidden;
305 | position: relative;
306 | z-index: 3;
307 | }
308 | div.CodeMirror-dragcursors {
309 | visibility: visible;
310 | }
311 |
312 | .CodeMirror-focused div.CodeMirror-cursors {
313 | visibility: visible;
314 | }
315 |
316 | .CodeMirror-selected { background: #d9d9d9; }
317 | .CodeMirror-focused .CodeMirror-selected { background: #d7d4f0; }
318 | .CodeMirror-crosshair { cursor: crosshair; }
319 | .CodeMirror-line::selection, .CodeMirror-line > span::selection, .CodeMirror-line > span > span::selection { background: #d7d4f0; }
320 | .CodeMirror-line::-moz-selection, .CodeMirror-line > span::-moz-selection, .CodeMirror-line > span > span::-moz-selection { background: #d7d4f0; }
321 |
322 | .cm-searching {
323 | background: #ffa;
324 | background: rgba(255, 255, 0, .4);
325 | }
326 |
327 | /* Used to force a border model for a node */
328 | .cm-force-border { padding-right: .1px; }
329 |
330 | @media print {
331 | /* Hide the cursor when printing */
332 | .CodeMirror div.CodeMirror-cursors {
333 | visibility: hidden;
334 | }
335 | }
336 |
337 | /* See issue #2901 */
338 | .cm-tab-wrap-hack:after { content: ''; }
339 |
340 | /* Help users use markselection to safely style text background */
341 | span.CodeMirror-selectedtext { background: none; }
342 |
--------------------------------------------------------------------------------
/src/refmt/refmt2.re:
--------------------------------------------------------------------------------
1 | open RefmtShared;
2 |
3 | [@bs.module "../../../../src/refmt/refmt.js"] external parseREEx : string => ast = "parseRE";
4 |
5 | [@bs.module "../../../../src/refmt/refmt.js"] external parseREIEx : string => ast = "parseREI";
6 |
7 | [@bs.module "../../../../src/refmt/refmt.js"] external parseMLEx : string => ast = "parseML";
8 |
9 | [@bs.module "../../../../src/refmt/refmt.js"] external parseMLIEx : string => ast = "parseMLI";
10 |
11 | [@bs.module "../../../../src/refmt/refmt.js"] external printRE : ast => string = "";
12 |
13 | [@bs.module "../../../../src/refmt/refmt.js"] external printREI : ast => string = "";
14 |
15 | [@bs.module "../../../../src/refmt/refmt.js"] external printML : ast => string = "";
16 |
17 | [@bs.module "../../../../src/refmt/refmt.js"] external printMLI : ast => string = "";
18 |
19 | [@bs.module "../../../../src/refmt/refmtOld.js"] external parseREOldEx : string => ast = "parseRE";
20 |
21 | [@bs.module "../../../../src/refmt/refmtOld.js"]
22 | external parseREIOldEx : string => ast = "parseREI";
23 |
24 | [@bs.module "../../../../src/refmt/refmtOld.js"] external printREOld : ast => string = "printRE";
25 |
26 | [@bs.module "../../../../src/refmt/refmtOld.js"] external printREIOld : ast => string = "printREI";
27 |
28 | let parseRE = (str) =>
29 | try (Ast(RE(parseREEx(str)))) {
30 | | Js.Exn.Error(parseError) => Error(RE(parseError))
31 | };
32 |
33 | let parseREI = (str) =>
34 | try (Ast(REI(parseREIEx(str)))) {
35 | | Js.Exn.Error(parseError) => Error(REI(parseError))
36 | };
37 |
38 | let parseML = (str) =>
39 | try (Ast(ML(parseMLEx(str)))) {
40 | | Js.Exn.Error(parseError) => Error(ML(parseError))
41 | };
42 |
43 | let parseMLI = (str) =>
44 | try (Ast(MLI(parseMLIEx(str)))) {
45 | | Js.Exn.Error(parseError) => Error(MLI(parseError))
46 | }; /* let printRE (Ast (RE ast)) => ( (printREEx ast));
47 | let printREI (Ast (REI ast)) => ( (printREIEx ast ));
48 | let printML (Ast (ML ast)) => ( (printMLEx ast));
49 | let printMLI (Ast (MLI ast)) => ( (printMLIEx ast )); */
50 |
51 | let parseREOld = (str) =>
52 | try (Ast(REO(parseREOldEx(str)))) {
53 | | Js.Exn.Error(parseError) => Error(REO(parseError))
54 | };
55 |
56 | let parseREIOld = (str) =>
57 | try (Ast(REOI(parseREIOldEx(str)))) {
58 | | Js.Exn.Error(parseError) => Error(REOI(parseError))
59 | };
60 |
61 | let (|?) = (a, b) =>
62 | switch a {
63 | | Some(a) => a
64 | | None => b
65 | } /* let (>!) (loc1: Location.t) (loc2: Location.t) => {
66 | let (_, line1, col1) = Location.get_pos_info loc1.loc_start;
67 | let (_, line2, col2) = Location.get_pos_info loc2.loc_start;
68 | line1 === line2 ? col1 > col2 : line1 > line2
69 | }; */ /* let string_of_code printer code => {
70 | ignore (Format.flush_str_formatter ());
71 | let f = Format.str_formatter;
72 | printer f code;
73 | Format.flush_str_formatter ()
74 | }; */ /* let parseRE code =>
75 | Ast (RE (Reason_toolchain.JS.canonical_implementation_with_comments (Lexing.from_string code)));
76 |
77 | let parseML code =>
78 | Ast (ML (Reason_toolchain.ML.canonical_implementation_with_comments (Lexing.from_string code)));
79 |
80 | let parseREI code =>
81 | Ast (REI (Reason_toolchain.JS.canonical_interface_with_comments (Lexing.from_string code)));
82 |
83 | let parseMLI code =>
84 | Ast (MLI (Reason_toolchain.ML.canonical_interface_with_comments (Lexing.from_string code)));
85 |
86 | let printML implementation =>
87 | string_of_code Reason_toolchain.ML.print_canonical_implementation_with_comments implementation;
88 |
89 | let printMLI signature =>
90 | string_of_code Reason_toolchain.ML.print_canonical_interface_with_comments signature;
91 |
92 | let printRE = string_of_code Reason_toolchain.JS.print_canonical_implementation_with_comments;
93 |
94 | let printREI = string_of_code Reason_toolchain.JS.print_canonical_interface_with_comments; */ /* |> */; /* let printREOld (Ast (REO ast)) => ( (printREOldEx ast ));
95 | let printREIOld (Ast (REOI ast)) => ( (printREIOldEx ast)); */
96 |
97 | let genErrors = (errors) =>
98 | switch errors {
99 | | [] => (UnknownLang, UnknownLang, "Sorry we don't have much info. Something went very wrong.")
100 | | [error, ..._] =>
101 | let thing =
102 | switch error {
103 | | REI(thing) => Js.Exn.message(thing)
104 | | RE(thing) => Js.Exn.message(thing)
105 | | ML(thing) => Js.Exn.message(thing)
106 | | MLI(thing) => Js.Exn.message(thing)
107 | | REO(thing) => Js.Exn.message(thing)
108 | | REOI(thing) => Js.Exn.message(thing)
109 | };
110 | (
111 | UnknownLang,
112 | UnknownLang,
113 | switch thing {
114 | | Some(str) => str
115 | | None => "Sorry we don't have much info. Something went very wrong."
116 | }
117 | ) /* switch (Js.Json.stringifyAny error) {
118 | | Some error => error
119 | | None => "Sorry we don't have much info. Something went very wrong."
120 | }) */ /* let error =
121 | List.fold_left
122 | (
123 | fun ((prevLoc, _, _) as prev) error => {
124 | let (optionLoc, _, _) as curr =
125 | switch error {
126 | | Syntaxerr.Error error =>
127 | /* ML */
128 | let loc = Syntaxerr.location_of_error error;
129 | let error = string_of_code Syntaxerr.report_error error;
130 | (Some loc, error, ML)
131 | | Syntax_util.Error loc error =>
132 | /* RE */
133 | let error = string_of_code Syntax_util.report_error error;
134 | (Some loc, error, RE)
135 | | finalExn => (None, Printexc.to_string finalExn, UnknownLang)
136 | };
137 | switch (optionLoc, prevLoc) {
138 | | (Some loc, Some prevLoc) => loc >! prevLoc ? curr : prev
139 | | (Some _, None) => curr
140 | | _ => prev
141 | }
142 | }
143 | )
144 | (None, "", UnknownLang)
145 | errors;
146 | switch error {
147 | | (None, message, inLang) => (inLang, UnknownLang, message)
148 | /* Reason error message printer doesn't include location, ML does */
149 | | (Some loc, message, inLang) when inLang == RE => (
150 | inLang,
151 | UnknownLang,
152 | string_of_code Location.print_loc loc ^ ":\n" ^ message
153 | )
154 | | (_, message, inLang) => (inLang, UnknownLang, message)
155 | } */
156 | };
157 |
158 | let attempts = (inLang, inType) =>
159 | switch (inLang, inType) {
160 | | (ML, Implementation) => [parseML]
161 | | (ML, Interface) => [parseMLI]
162 | | (RE, Implementation) => [parseRE]
163 | | (RE, Interface) => [parseREI]
164 | | (REO, Implementation) => [parseREI]
165 | | (REO, Interface) => [parseREI]
166 | | (UnknownLang, Implementation) => [parseRE, parseREOld, parseML]
167 | | (UnknownLang, Interface) => [parseREI, parseREIOld, parseMLI]
168 | | (ML, UnknownType) => [parseML, parseMLI]
169 | | (RE, UnknownType) => [parseRE, parseREI]
170 | | (REO, UnknownType) => [parseREOld, parseREIOld]
171 | | (UnknownLang, UnknownType) => [parseRE, parseREI, parseREOld, parseREIOld, parseML, parseMLI]
172 | };
173 |
174 | let optionalString = fun | Some(s:string) => s | None => "";
175 |
176 | let refmt = (code, inLang, inType, outLang) => {
177 | let parsersToTry = attempts(inLang, inType);
178 | let results = List.map((parser) => parser(code), parsersToTry);
179 | try {
180 | let resultList =
181 | List.find_all(
182 | (res) =>
183 | switch res {
184 | | Error(_) => false
185 | | _ => true
186 | },
187 | results
188 | );
189 | let result =
190 | switch (resultList, results) {
191 | | ([], [error])
192 | | ([], [error, ..._]) => error
193 | | ([result], _)
194 | | ([result, ..._], _) => result
195 | | (_, _) => assert false
196 | };
197 | let (trueOut, printedResult) =
198 | switch (outLang, result) {
199 | | (RE, Ast(ML(ast)))
200 | | (RE, Ast(RE(ast)))
201 | | (RE, Ast(REO(ast)))
202 | | (UnknownLang, Ast(REO(ast)))
203 | | (UnknownLang, Ast(ML(ast))) => (RE, printRE(ast))
204 | | (REO, Ast(ML(ast)))
205 | | (REO, Ast(RE(ast)))
206 | | (REO, Ast(REO(ast))) => (REO, printREOld(ast))
207 | | (ML, Ast(ML(ast)))
208 | | (ML, Ast(RE(ast)))
209 | | (ML, Ast(REO(ast)))
210 | | (UnknownLang, Ast(RE(ast))) => (ML, printML(ast))
211 | | (RE, Ast(MLI(ast)))
212 | | (RE, Ast(REI(ast)))
213 | | (RE, Ast(REOI(ast)))
214 | | (UnknownLang, Ast(REOI(ast)))
215 | | (UnknownLang, Ast(MLI(ast))) => (RE, printREI(ast))
216 | | (REO, Ast(MLI(ast)))
217 | | (REO, Ast(REI(ast)))
218 | | (REO, Ast(REOI(ast))) => (REO, printREIOld(ast))
219 | | (ML, Ast(MLI(ast)))
220 | | (ML, Ast(REI(ast)))
221 | | (ML, Ast(REOI(ast)))
222 | | (UnknownLang, Ast(REI(ast))) => (ML, printMLI(ast))
223 | | (_, Error(error)) =>
224 | switch error {
225 | | REI(thing) => raise(Failure(Js.Exn.message(thing)|>optionalString))
226 | | RE(thing) => raise(Failure(Js.Exn.message(thing)|>optionalString))
227 | | ML(thing) => raise(Failure(Js.Exn.message(thing)|>optionalString))
228 | | MLI(thing) => raise(Failure(Js.Exn.message(thing)|>optionalString))
229 | | REO(thing) => raise(Failure(Js.Exn.message(thing)|>optionalString))
230 | | REOI(thing) => raise(Failure(Js.Exn.message(thing)|>optionalString))
231 | }
232 | };
233 | let trueIn =
234 | switch result {
235 | | Ast(ML(_))
236 | | Ast(MLI(_)) => ML
237 | | Ast(RE(_))
238 | | Ast(REI(_)) => RE
239 | | Ast(REO(_))
240 | | Ast(REOI(_)) => REO
241 | | Error(_) => UnknownLang
242 | };
243 | Result.Ok((trueIn, trueOut, printedResult))
244 | } {
245 | | a => {
246 | Result.Error(a |> Printexc.to_string)
247 | }
248 | }
249 | };
250 |
--------------------------------------------------------------------------------
/docs/ocamlDoc.css:
--------------------------------------------------------------------------------
1 | /**
2 | * This CSS file for documentation generation embeds Normalize.css
3 | * https://necolas.github.io/normalize.css/4.1.1/normalize.css
4 | *
5 | * And then specifies a bunch of custom styles for the ocamldoc generation:
6 | *
7 | */
8 |
9 |
10 |
11 |
12 | /* bodyFontSize */
13 | font-size: 14px;
14 |
15 | /* codeFontSize */
16 | font-size: 13px
17 |
18 |
19 | /* infoBackgroundColor */
20 | background-color: #30302d;
21 |
22 | /* linkColor */
23 | color: #cec47f;
24 | /* linkColorActive */
25 | color: #faf0ab;
26 |
27 |
28 |
29 | /**
30 | * Space Gray Dark:
31 | * ================
32 | */
33 | /* backgroundColorDark */
34 | background-color: #262b36;
35 |
36 | /* backgroundColor */
37 | background-color: #2b303b;
38 |
39 | /* backgroundColorPanel */
40 | background-color: #313641;
41 |
42 | /* borderLeftColorPanel */
43 | border-left: 4px solid rgba(101,115,126, 0.2);
44 |
45 | /* borderColorInlineCode */
46 | border: 1px solid #3b3f4a;
47 |
48 | /* backgroundColorInlineCode */
49 | background-color: #393d48;
50 |
51 | /* backgroundColorInlineBorder */
52 | border: 1px solid #474b56;
53 |
54 | /* colorText */
55 | color: #c0c5ce;
56 |
57 | /* primaryColor */
58 | color: #8fa1b3;
59 |
60 | /* */
61 | /* colorFadedText (comment) */
62 | 5px solid rgba(101,115,126,1);
63 |
64 | /* let */
65 | /* colorKeyword (purple) */
66 | color: #b48ead;
67 |
68 | /* colorRed */
69 | color: #BF616A;
70 | /* colorRedActive */
71 | color: #CB6D77;
72 |
73 | /* colorGreen */
74 | color: #91B376;
75 |
76 | /* colorGreenActive */
77 | color: #97B98c;
78 |
79 | /* colorYellow */
80 | color: #EBCB8B;
81 |
82 | /* colorYellowActive */
83 | color: #FBDB9B;
84 |
85 | /* colorCyan */
86 | color: #96B5B4;
87 |
88 |
89 |
90 | /*
91 |
92 |
93 | TopInfoBg:
94 | #424240
95 |
96 | TopInfoCodeBg:
97 | #545454
98 |
99 |
100 | InfoBgLeftBorder:
101 | #666664
102 |
103 | KeyWord (let type etc):
104 | #ecac9d
105 |
106 | Type:
107 | #ff0001;
108 |
109 | Comment:
110 | #aeaea1;
111 |
112 |
113 | .navbar > a:nth-child(1n) {
114 | border-bottom: 4px solid #d7df9d;
115 | }
116 |
117 | .navbar > a:nth-child(2n) {
118 | border-bottom: 4px solid #ef95a4;
119 | }
120 |
121 | .navbar > a:nth-child(3n) {
122 | border-bottom: 4px solid #aabbd0;
123 | }
124 |
125 | .navbar > a:nth-child(4n) {
126 | border-bottom: 4px solid #cec47f;
127 | }
128 |
129 | .navbar > a:nth-child(5n) {
130 | border-bottom: 4px solid #b58900;
131 | }
132 |
133 |
134 | /*! normalize.css v4.1.1 | MIT License | github.com/necolas/normalize.css */
135 |
136 | /**
137 | * 1. Change the default font family in all browsers (opinionated).
138 | * 2. Prevent adjustments of font size after orientation changes in IE and iOS.
139 | */
140 |
141 | html {
142 | font-family: sans-serif; /* 1 */
143 | -ms-text-size-adjust: 100%; /* 2 */
144 | -webkit-text-size-adjust: 100%; /* 2 */
145 | }
146 |
147 | /**
148 | * Remove the margin in all browsers (opinionated).
149 | */
150 |
151 | body {
152 | margin: 0;
153 | }
154 |
155 | /* HTML5 display definitions
156 | ========================================================================== */
157 |
158 | /**
159 | * Add the correct display in IE 9-.
160 | * 1. Add the correct display in Edge, IE, and Firefox.
161 | * 2. Add the correct display in IE.
162 | */
163 |
164 | article,
165 | aside,
166 | details, /* 1 */
167 | figcaption,
168 | figure,
169 | footer,
170 | header,
171 | main, /* 2 */
172 | menu,
173 | nav,
174 | section,
175 | summary { /* 1 */
176 | display: block;
177 | }
178 |
179 | /**
180 | * Add the correct display in IE 9-.
181 | */
182 |
183 | audio,
184 | canvas,
185 | progress,
186 | video {
187 | display: inline-block;
188 | }
189 |
190 | /**
191 | * Add the correct display in iOS 4-7.
192 | */
193 |
194 | audio:not([controls]) {
195 | display: none;
196 | height: 0;
197 | }
198 |
199 | /**
200 | * Add the correct vertical alignment in Chrome, Firefox, and Opera.
201 | */
202 |
203 | progress {
204 | vertical-align: baseline;
205 | }
206 |
207 | /**
208 | * Add the correct display in IE 10-.
209 | * 1. Add the correct display in IE.
210 | */
211 |
212 | template, /* 1 */
213 | [hidden] {
214 | display: none;
215 | }
216 |
217 | /* Links
218 | ========================================================================== */
219 |
220 | /**
221 | * 1. Remove the gray background on active links in IE 10.
222 | * 2. Remove gaps in links underline in iOS 8+ and Safari 8+.
223 | */
224 |
225 | a {
226 | background-color: transparent; /* 1 */
227 | -webkit-text-decoration-skip: objects; /* 2 */
228 | }
229 |
230 | /**
231 | * Remove the outline on focused links when they are also active or hovered
232 | * in all browsers (opinionated).
233 | */
234 |
235 | a:active,
236 | a:hover {
237 | outline-width: 0;
238 | }
239 |
240 | /* Text-level semantics
241 | ========================================================================== */
242 |
243 | /**
244 | * 1. Remove the bottom border in Firefox 39-.
245 | * 2. Add the correct text decoration in Chrome, Edge, IE, Opera, and Safari.
246 | */
247 |
248 | abbr[title] {
249 | border-bottom: none; /* 1 */
250 | text-decoration: underline; /* 2 */
251 | text-decoration: underline dotted; /* 2 */
252 | }
253 |
254 | /**
255 | * Prevent the duplicate application of `bolder` by the next rule in Safari 6.
256 | */
257 |
258 | b,
259 | strong {
260 | font-weight: inherit;
261 | }
262 |
263 | /**
264 | * Add the correct font weight in Chrome, Edge, and Safari.
265 | */
266 |
267 | b,
268 | strong {
269 | font-weight: bolder;
270 | }
271 |
272 | /**
273 | * Add the correct font style in Android 4.3-.
274 | */
275 |
276 | dfn {
277 | font-style: italic;
278 | }
279 |
280 | /**
281 | * Correct the font size and margin on `h1` elements within `section` and
282 | * `article` contexts in Chrome, Firefox, and Safari.
283 | */
284 |
285 | h1 {
286 | font-size: 2em;
287 | margin: 0.67em 0;
288 | }
289 |
290 | /**
291 | * Add the correct background and color in IE 9-.
292 | */
293 |
294 | mark {
295 | background-color: #ff0;
296 | color: #000;
297 | }
298 |
299 | /**
300 | * Add the correct font size in all browsers.
301 | */
302 |
303 | small {
304 | font-size: 80%;
305 | }
306 |
307 | /**
308 | * Prevent `sub` and `sup` elements from affecting the line height in
309 | * all browsers.
310 | */
311 |
312 | sub,
313 | sup {
314 | font-size: 75%;
315 | line-height: 0;
316 | position: relative;
317 | vertical-align: baseline;
318 | }
319 |
320 | sub {
321 | bottom: -0.25em;
322 | }
323 |
324 | sup {
325 | top: -0.5em;
326 | }
327 |
328 | /* Embedded content
329 | ========================================================================== */
330 |
331 | /**
332 | * Remove the border on images inside links in IE 10-.
333 | */
334 |
335 | img {
336 | border-style: none;
337 | }
338 |
339 | /**
340 | * Hide the overflow in IE.
341 | */
342 |
343 | svg:not(:root) {
344 | overflow: hidden;
345 | }
346 |
347 | /* Grouping content
348 | ========================================================================== */
349 |
350 | /**
351 | * 1. Correct the inheritance and scaling of font size in all browsers.
352 | * 2. Correct the odd `em` font sizing in all browsers.
353 | */
354 |
355 | code,
356 | kbd,
357 | pre,
358 | samp {
359 | font-family: monospace, monospace; /* 1 */
360 | font-size: 1em; /* 2 */
361 | }
362 |
363 | /**
364 | * Add the correct margin in IE 8.
365 | */
366 |
367 | figure {
368 | margin: 1em 40px;
369 | }
370 |
371 | /**
372 | * 1. Add the correct box sizing in Firefox.
373 | * 2. Show the overflow in Edge and IE.
374 | */
375 |
376 | hr {
377 | box-sizing: content-box; /* 1 */
378 | height: 0; /* 1 */
379 | overflow: visible; /* 2 */
380 | }
381 |
382 | /* Forms
383 | ========================================================================== */
384 |
385 | /**
386 | * 1. Change font properties to `inherit` in all browsers (opinionated).
387 | * 2. Remove the margin in Firefox and Safari.
388 | */
389 |
390 | button,
391 | input,
392 | select,
393 | textarea {
394 | font: inherit; /* 1 */
395 | margin: 0; /* 2 */
396 | }
397 |
398 | /**
399 | * Restore the font weight unset by the previous rule.
400 | */
401 |
402 | optgroup {
403 | font-weight: bold;
404 | }
405 |
406 | /**
407 | * Show the overflow in IE.
408 | * 1. Show the overflow in Edge.
409 | */
410 |
411 | button,
412 | input { /* 1 */
413 | overflow: visible;
414 | }
415 |
416 | /**
417 | * Remove the inheritance of text transform in Edge, Firefox, and IE.
418 | * 1. Remove the inheritance of text transform in Firefox.
419 | */
420 |
421 | button,
422 | select { /* 1 */
423 | text-transform: none;
424 | }
425 |
426 | /**
427 | * 1. Prevent a WebKit bug where (2) destroys native `audio` and `video`
428 | * controls in Android 4.
429 | * 2. Correct the inability to style clickable types in iOS and Safari.
430 | */
431 |
432 | button,
433 | html [type="button"], /* 1 */
434 | [type="reset"],
435 | [type="submit"] {
436 | -webkit-appearance: button; /* 2 */
437 | }
438 |
439 | /**
440 | * Remove the inner border and padding in Firefox.
441 | */
442 |
443 | button::-moz-focus-inner,
444 | [type="button"]::-moz-focus-inner,
445 | [type="reset"]::-moz-focus-inner,
446 | [type="submit"]::-moz-focus-inner {
447 | border-style: none;
448 | padding: 0;
449 | }
450 |
451 | /**
452 | * Restore the focus styles unset by the previous rule.
453 | */
454 |
455 | button:-moz-focusring,
456 | [type="button"]:-moz-focusring,
457 | [type="reset"]:-moz-focusring,
458 | [type="submit"]:-moz-focusring {
459 | outline: 1px dotted ButtonText;
460 | }
461 |
462 | /**
463 | * Change the border, margin, and padding in all browsers (opinionated).
464 | */
465 |
466 | fieldset {
467 | border: 1px solid #c0c0c0;
468 | margin: 0 2px;
469 | padding: 0.35em 0.625em 0.75em;
470 | }
471 |
472 | /**
473 | * 1. Correct the text wrapping in Edge and IE.
474 | * 2. Correct the color inheritance from `fieldset` elements in IE.
475 | * 3. Remove the padding so developers are not caught out when they zero out
476 | * `fieldset` elements in all browsers.
477 | */
478 |
479 | legend {
480 | box-sizing: border-box; /* 1 */
481 | color: inherit; /* 2 */
482 | display: table; /* 1 */
483 | max-width: 100%; /* 1 */
484 | padding: 0; /* 3 */
485 | white-space: normal; /* 1 */
486 | }
487 |
488 | /**
489 | * Remove the default vertical scrollbar in IE.
490 | */
491 |
492 | textarea {
493 | overflow: auto;
494 | }
495 |
496 | /**
497 | * 1. Add the correct box sizing in IE 10-.
498 | * 2. Remove the padding in IE 10-.
499 | */
500 |
501 | [type="checkbox"],
502 | [type="radio"] {
503 | box-sizing: border-box; /* 1 */
504 | padding: 0; /* 2 */
505 | }
506 |
507 | /**
508 | * Correct the cursor style of increment and decrement buttons in Chrome.
509 | */
510 |
511 | [type="number"]::-webkit-inner-spin-button,
512 | [type="number"]::-webkit-outer-spin-button {
513 | height: auto;
514 | }
515 |
516 | /**
517 | * 1. Correct the odd appearance in Chrome and Safari.
518 | * 2. Correct the outline style in Safari.
519 | */
520 |
521 | [type="search"] {
522 | -webkit-appearance: textfield; /* 1 */
523 | outline-offset: -2px; /* 2 */
524 | }
525 |
526 | /**
527 | * Remove the inner padding and cancel buttons in Chrome and Safari on OS X.
528 | */
529 |
530 | [type="search"]::-webkit-search-cancel-button,
531 | [type="search"]::-webkit-search-decoration {
532 | -webkit-appearance: none;
533 | }
534 |
535 | /**
536 | * Correct the text style of placeholders in Chrome, Edge, and Safari.
537 | */
538 |
539 | ::-webkit-input-placeholder {
540 | color: inherit;
541 | opacity: 0.54;
542 | }
543 |
544 | /**
545 | * 1. Correct the inability to style clickable types in iOS and Safari.
546 | * 2. Change font properties to `inherit` in Safari.
547 | */
548 |
549 | ::-webkit-file-upload-button {
550 | -webkit-appearance: button; /* 1 */
551 | font: inherit; /* 2 */
552 | }
553 |
554 |
555 |
556 |
557 | /**
558 | * CUSTOM CSS:
559 | */
560 |
561 | ul,ol {
562 | padding: 0;
563 | margin: 10 0 10px 25px
564 | }
565 |
566 | ul ul, ul ol, ol ol, ol ul {
567 | margin-bottom: 0;
568 | }
569 |
570 | li {
571 | line-height: 20px
572 | }
573 |
574 | * {
575 | box-sizing: border-box;
576 | }
577 |
578 |
579 | body {
580 | font-family: "Helvetica", "Open Sans","Helvetica Neue",Helvetica,Arial,sans-serif;
581 | /* bodyFontSize */
582 | font-size: 14px;
583 | margin: 0px;
584 | line-height: 20px;
585 | /* backgroundColor */
586 | background-color: #2b303b;
587 |
588 | /* colorText */
589 | color: #c0c5ce;
590 | padding: 40px;
591 | padding-top: 50px;
592 | }
593 |
594 | td.module {
595 | font-family: Menlo,Menlo,Consolas,"Courier New",monospace;
596 | /* codeFontSize */
597 | font-size: 13px
598 | }
599 |
600 |
601 | code, pre {
602 | font-family: Menlo,Menlo,Consolas,"Courier New",monospace;
603 | /* codeFontSize */
604 | font-size: 13px;
605 | color: #333;
606 | }
607 |
608 | a {
609 | color: inherit;
610 | /* colorYellow */
611 | text-decoration: none;
612 | -webkit-transition: color 0.1s ease-out;
613 | -moz-transition: color 0.1s ease-out;
614 | -o-transition: color 0.1s ease-out;
615 | transition: color 0.1s ease-out;
616 | }
617 |
618 | a:hover,a:focus {
619 | color: inherit;
620 | /* colorYellowActive */
621 | text-decoration: none;
622 | outline: none;
623 | -webkit-transition: color 0.1s ease-out;
624 | -moz-transition: color 0.1s ease-out;
625 | -o-transition: color 0.1s ease-out;
626 | transition: color 0.1s ease-out;
627 | }
628 |
629 | .typetable {
630 | /* So that top level pre's margin-bottom isn't conflicting */
631 | margin-top: -10px;
632 | }
633 |
634 | pre, .typetable {
635 | border-radius: 0;
636 | border: none;
637 | /* codeFontSize */
638 | font-size: 13px;
639 | }
640 |
641 | .constructor {
642 | /* colorRed */
643 | color: #BF616A;
644 | }
645 |
646 | .keyword {
647 | /* colorKeyword (purple) */
648 | color: #b48ead;
649 | }
650 |
651 | .type {
652 | color: #BF616A;
653 | }
654 |
655 | .string {
656 | color: #91B376;
657 | }
658 |
659 | pre {
660 | display: block;
661 | line-height: 20px;
662 | word-break: break-all;
663 | word-wrap: break-word;
664 | white-space: pre;
665 | white-space: pre-wrap;
666 | }
667 |
668 | pre.prettyprint {
669 | margin-bottom: 20px
670 | }
671 |
672 | code {
673 | white-space: nowrap;
674 | -webkit-border-radius: 0;
675 | -moz-border-radius: 0;
676 | -ms-border-radius: 0;
677 | -o-border-radius: 0;
678 | border-radius: 0
679 | }
680 |
681 | /**
682 | * code.code are typically inline code, in an info section - not code snippets.
683 | */
684 | .info code.code, .param_info code.code {
685 | /* backgroundColorInlineCode */
686 | background-color: #393d48;
687 | border-radius:1px;
688 | padding: 1px 3px 1px 3px;
689 | }
690 |
691 | /* Creates better underline for anything inside an anchor (better than standard
692 | * text decoration) that is inside an info or param_info. */
693 | body > a > *,
694 | p > a > *,
695 | li > a > *,
696 | .info > a > *,
697 | .param_info > a > * {
698 | /* colorFadedText (comment) */
699 | border-bottom: 1px dotted #EBCB8B;
700 | }
701 |
702 | body > a:hover > *,
703 | body > a:focus > *,
704 | p > a:hover > *,
705 | p > a:focus > *,
706 | li > a:hover > *,
707 | li > a:focus > *,
708 | .info > a:hover > *,
709 | .info > a:focus > *,
710 | .param_info > a:hover > *,
711 | .param_info > a:focus > * {
712 | /* colorYellow */
713 | border-bottom: 1px solid #EBCB8B;
714 | }
715 |
716 |
717 | /**
718 | * Anchors appearing in pre or code do not contain more pre or code typically,
719 | * and usually only contain text: which is why we must target their anchor directly.
720 | * Which didn't work when the anchor had a code child (bottom borders do not render)
721 | */
722 | pre > a,
723 | code > a,
724 | .typetable a {
725 | /* colorFadedText (comment) */
726 | border-bottom: 1px dotted #EBCB8B;
727 | }
728 |
729 | pre > a:focus,
730 | pre > a:hover,
731 | code > a:focus,
732 | code > a:hover,
733 | .typetable a:focus,
734 | .typetable a:hover {
735 | /* colorYellow */
736 | border-bottom: 1px solid #EBCB8B;
737 | }
738 |
739 | /**
740 | * For named arguments documentation: Give the named arguments a little pop.
741 | */
742 | .param_info > code.code:nth-child(1) {
743 | /* backgroundColorInlineBorder */
744 | border: 1px solid #474b56;
745 | }
746 |
747 |
748 |
749 | pre code {
750 | color: inherit;
751 | white-space: pre;
752 | white-space: pre-wrap;
753 | background-color: transparent;
754 | border: 0
755 | }
756 |
757 | h1, h2, h3, h4, h5, h6 {
758 | margin: 10px 0;
759 | font-weight: bold;
760 | line-height: 20px;
761 | color: inherit;
762 | text-rendering: optimizelegibility;
763 | }
764 |
765 | h1 {
766 | font-size: 22px;
767 | }
768 |
769 | h2 {
770 | font-size: 20px
771 | }
772 |
773 | h3 {
774 | font-size: 18px
775 | }
776 |
777 | h4 {
778 | font-size: 16px
779 | }
780 |
781 | h5 {
782 | font-size: 14px
783 | }
784 |
785 | /**
786 | * The ocamldoc generator uses these for primary headers:
787 | */
788 | h6 {
789 | font-size: 18px;
790 | }
791 |
792 | /**
793 | * To fix the formatting, we hide all the brs, and add a bunch of space above the h6's.
794 | */
795 | h6 {
796 | margin-top:40px;
797 | }
798 |
799 | /**
800 | * Ocamldoc generator uses .h7 as subheaders
801 | */
802 | .h7 {
803 | /* bodyFontSize */
804 | font-size: 14px;
805 | font-weight: bold;
806 | }
807 |
808 | body > h1 {
809 | /* backgroundColorDark */
810 | background-color: #252932;
811 | margin-right: -40px;
812 | margin-left: -40px;
813 | padding-top: 10px;
814 | padding-left: 20px;
815 | padding-right: 20px;
816 | padding-bottom: 10px;
817 | }
818 |
819 | body > h1:first-of-type {
820 | text-align:right;
821 | position: fixed;
822 | z-index: 90;
823 | left: 0;
824 | right: 0;
825 | margin: 0;
826 | top: 0;
827 | }
828 |
829 | h1 > a {
830 | /* colorRed */
831 | color: #BF616A;
832 | }
833 | h1 > a:active, h1 > a:focus, h1 > a:hover {
834 | /* colorRedActive */
835 | color: #CB6D77;
836 | }
837 |
838 | .navbar {
839 | position: fixed;
840 | left: 0; right: 0;
841 | margin-top: -50px; /* Match body padding */
842 | margin-bottom: 0px;
843 | padding-top: 0px;
844 | padding-left: 20px;
845 | padding-right: 20px;
846 | padding-bottom: 0px;
847 | z-index: 91;
848 | }
849 |
850 |
851 | .navbar > a {
852 | display: inline-block;
853 | font-weight: bold;
854 | color: #999;
855 | text-decoration: none;
856 | padding-top: 14px;
857 | padding-left: 5px;
858 | padding-right: 5px;
859 | height: 40px;
860 | border-bottom: 4px solid;
861 | }
862 |
863 | .navbar > a:nth-child(1n) {
864 | /* colorGreen */
865 | border-bottom: 4px solid #91B376;
866 | }
867 |
868 | .navbar > a:nth-child(2n) {
869 | /* colorRed */
870 | border-bottom: 4px solid #BF616A;
871 | }
872 |
873 | .navbar > a:nth-child(3n) {
874 | /* colorCyan */
875 | border-bottom: 4px solid #96B5B4;
876 | }
877 |
878 | .navbar > a:nth-child(4n) {
879 | border-bottom: 4px solid #cec47f;
880 | }
881 |
882 | .navbar > a:nth-child(5n) {
883 | border-bottom: 4px solid #b58900;
884 | }
885 |
886 |
887 | .navbar a:hover, a:focus {
888 | opacity: 1.0;
889 | text-decoration: none
890 | }
891 |
892 |
893 |
894 | .indextable {
895 | /* backgroundColor */
896 | background-color: #2b303b;
897 | }
898 |
899 | .indextable td {
900 | padding-left: 5px;
901 | padding-right: 5px;
902 | }
903 |
904 | .indexlist {
905 | margin-top: 12px;
906 | }
907 |
908 |
909 | body > .info {
910 | /* backgroundColorPanel */
911 | background-color: #313641;
912 | padding: 20px;
913 | margin-left:20px;
914 | margin-top: 15px;
915 | /* So that the top level pre's 30px margin-top is halfed, but param info's
916 | * are sucked up into the top level .info's */
917 | /* colorFadedText (comment) */
918 | border-left: 5px solid rgba(101,115,126, 0.2);
919 | }
920 |
921 |
922 |
923 | body > .param_info {
924 | /* backgroundColorPanel */
925 | margin-top:1px;
926 | background-color: #313641;
927 | margin-left: 20px;
928 | padding: 15px;
929 | /* colorGreen */
930 | border-left: 5px solid #91B376;
931 | }
932 |
933 | pre + .info, table + .info {
934 | /* margin-bottom:15px; */
935 | }
936 |
937 | /**
938 | * Each module entry should have proper spacing.
939 | */
940 | body > pre {
941 | margin-top: 20px;
942 | margin-bottom: 10px;
943 | margin-left: 0px;
944 | margin-right: 0px;
945 | }
946 |
947 |
948 | .paramstable {
949 | /* codeFontSize */
950 | font-size: 13px;
951 | }
952 |
953 |
954 | .info.module.top {
955 | /* By default, free floating text in the top info will have a lighter weight and larger size.
956 | * Then inner tags style will then bring it back down to standard weight/size, but the first
957 | * free floating text which describes the module is *not* in a p tag so will have this nicer look */
958 | font-size: 18px;
959 | /* colorText */
960 | color: #c0c5ce;
961 | /* margin-left: -50px; */
962 | /* margin-right: -50px; */
963 | margin-left: 0px;
964 | }
965 |
966 | /* The first block of text */
967 | .info.module.top > *:nth-child(1) {
968 | font-size: 16px;
969 | font-weight: 300;
970 | padding-bottom: 10px;
971 | }
972 |
973 | .info.module.top > code, .info.module.top > .code,
974 | .info.module.top > p > .code {
975 | /* background-color: #545454; */
976 | }
977 |
978 |
979 | .info.module.top + hr {
980 | position: relative;
981 | font-weight: normal;
982 | font-size: 24px;
983 | border:none;
984 | line-height: normal;
985 | display: inline-block;
986 | margin-top: 0;
987 | margin-left: -25px;
988 | color: white;
989 | white-space: nowrap;
990 | -webkit-transition: all 0.1s ease-out;
991 | -moz-transition: all 0.1s ease-out;
992 | -o-transition: all 0.1s ease-out;
993 | transition: all 0.1s ease-out;
994 | opacity: 0.8;
995 | -webkit-backface-visibility: hidden
996 | }
997 | /**
998 | * See the Set documentation for why we need this:
999 | */
1000 | .info > .codepre > code > br {
1001 | display:none;
1002 | }
1003 | .codepre {
1004 | padding:10px;
1005 | /* backgroundColorInlineCode */
1006 | background-color: #393d48;
1007 | }
1008 | .info > .codepre > .code {
1009 | font-weight: normal;
1010 | /* No background color on inner code lines/elements because the outer .codepre has
1011 | * provided the background color. */
1012 | background-color: transparent;
1013 | }
1014 |
1015 | /* .info.module.top + hr:after { */
1016 | /* content: " "; */
1017 | /* display: block; */
1018 | /* border-top: 4px solid #3d3d3b; */
1019 | /* opacity: 0.8; */
1020 | /* width: 0; */
1021 | /* height: 0; */
1022 | /* position: absolute; */
1023 | /* bottom: -4px; */
1024 | /* border-left: 5px solid transparent; */
1025 | /* left: 0 */
1026 | /* } */
1027 | /* */
1028 | /* hr:after { */
1029 | /* border-top-color: #b9221f; */
1030 | /* } */
1031 |
1032 |
1033 | pre, code, .code {
1034 | /* colorText */
1035 | color: #c0c5ce;
1036 | }
1037 |
1038 | pre, code, .code, pre *, code *, .code * {
1039 | /* codeFontSize */
1040 | font-size: 13px;
1041 | }
1042 |
1043 | .typefieldcomment {
1044 | visibility:hidden;
1045 | }
1046 |
1047 | .typefieldcomment > .info {
1048 | visibility: visible;
1049 | }
1050 |
1051 | pre {
1052 | padding-left: 0px; /* More to fix the trailing } */
1053 | }
1054 |
1055 | .info, b, ol *, ul *, p {
1056 | /* bodyFontSize */
1057 | font-size: 14px;
1058 | }
1059 |
1060 |
1061 | .navbar {
1062 | font-size: 18px;
1063 | }
1064 |
1065 | /* hacks for documents with .lstframe code listings */
1066 | td[bgcolor=white] {
1067 | /* removes white blocks next to certain code listings */
1068 | display: none;
1069 | }
1070 |
1071 | .lstframe {
1072 | background-color: transparent !important;
1073 | }
1074 |
--------------------------------------------------------------------------------
/src/css/ocamlDoc.css:
--------------------------------------------------------------------------------
1 | /**
2 | * This CSS file for documentation generation embeds Normalize.css
3 | * https://necolas.github.io/normalize.css/4.1.1/normalize.css
4 | *
5 | * And then specifies a bunch of custom styles for the ocamldoc generation:
6 | *
7 | */
8 |
9 |
10 |
11 |
12 | /* bodyFontSize */
13 | font-size: 14px;
14 |
15 | /* codeFontSize */
16 | font-size: 13px
17 |
18 |
19 | /* infoBackgroundColor */
20 | background-color: #30302d;
21 |
22 | /* linkColor */
23 | color: #cec47f;
24 | /* linkColorActive */
25 | color: #faf0ab;
26 |
27 |
28 |
29 | /**
30 | * Space Gray Dark:
31 | * ================
32 | */
33 | /* backgroundColorDark */
34 | background-color: #262b36;
35 |
36 | /* backgroundColor */
37 | background-color: #2b303b;
38 |
39 | /* backgroundColorPanel */
40 | background-color: #313641;
41 |
42 | /* borderLeftColorPanel */
43 | border-left: 4px solid rgba(101,115,126, 0.2);
44 |
45 | /* borderColorInlineCode */
46 | border: 1px solid #3b3f4a;
47 |
48 | /* backgroundColorInlineCode */
49 | background-color: #393d48;
50 |
51 | /* backgroundColorInlineBorder */
52 | border: 1px solid #474b56;
53 |
54 | /* colorText */
55 | color: #c0c5ce;
56 |
57 | /* primaryColor */
58 | color: #8fa1b3;
59 |
60 | /* */
61 | /* colorFadedText (comment) */
62 | 5px solid rgba(101,115,126,1);
63 |
64 | /* let */
65 | /* colorKeyword (purple) */
66 | color: #b48ead;
67 |
68 | /* colorRed */
69 | color: #BF616A;
70 | /* colorRedActive */
71 | color: #CB6D77;
72 |
73 | /* colorGreen */
74 | color: #91B376;
75 |
76 | /* colorGreenActive */
77 | color: #97B98c;
78 |
79 | /* colorYellow */
80 | color: #EBCB8B;
81 |
82 | /* colorYellowActive */
83 | color: #FBDB9B;
84 |
85 | /* colorCyan */
86 | color: #96B5B4;
87 |
88 |
89 |
90 | /*
91 |
92 |
93 | TopInfoBg:
94 | #424240
95 |
96 | TopInfoCodeBg:
97 | #545454
98 |
99 |
100 | InfoBgLeftBorder:
101 | #666664
102 |
103 | KeyWord (let type etc):
104 | #ecac9d
105 |
106 | Type:
107 | #ff0001;
108 |
109 | Comment:
110 | #aeaea1;
111 |
112 |
113 | .navbar > a:nth-child(1n) {
114 | border-bottom: 4px solid #d7df9d;
115 | }
116 |
117 | .navbar > a:nth-child(2n) {
118 | border-bottom: 4px solid #ef95a4;
119 | }
120 |
121 | .navbar > a:nth-child(3n) {
122 | border-bottom: 4px solid #aabbd0;
123 | }
124 |
125 | .navbar > a:nth-child(4n) {
126 | border-bottom: 4px solid #cec47f;
127 | }
128 |
129 | .navbar > a:nth-child(5n) {
130 | border-bottom: 4px solid #b58900;
131 | }
132 |
133 |
134 | /*! normalize.css v4.1.1 | MIT License | github.com/necolas/normalize.css */
135 |
136 | /**
137 | * 1. Change the default font family in all browsers (opinionated).
138 | * 2. Prevent adjustments of font size after orientation changes in IE and iOS.
139 | */
140 |
141 | html {
142 | font-family: sans-serif; /* 1 */
143 | -ms-text-size-adjust: 100%; /* 2 */
144 | -webkit-text-size-adjust: 100%; /* 2 */
145 | }
146 |
147 | /**
148 | * Remove the margin in all browsers (opinionated).
149 | */
150 |
151 | body {
152 | margin: 0;
153 | }
154 |
155 | /* HTML5 display definitions
156 | ========================================================================== */
157 |
158 | /**
159 | * Add the correct display in IE 9-.
160 | * 1. Add the correct display in Edge, IE, and Firefox.
161 | * 2. Add the correct display in IE.
162 | */
163 |
164 | article,
165 | aside,
166 | details, /* 1 */
167 | figcaption,
168 | figure,
169 | footer,
170 | header,
171 | main, /* 2 */
172 | menu,
173 | nav,
174 | section,
175 | summary { /* 1 */
176 | display: block;
177 | }
178 |
179 | /**
180 | * Add the correct display in IE 9-.
181 | */
182 |
183 | audio,
184 | canvas,
185 | progress,
186 | video {
187 | display: inline-block;
188 | }
189 |
190 | /**
191 | * Add the correct display in iOS 4-7.
192 | */
193 |
194 | audio:not([controls]) {
195 | display: none;
196 | height: 0;
197 | }
198 |
199 | /**
200 | * Add the correct vertical alignment in Chrome, Firefox, and Opera.
201 | */
202 |
203 | progress {
204 | vertical-align: baseline;
205 | }
206 |
207 | /**
208 | * Add the correct display in IE 10-.
209 | * 1. Add the correct display in IE.
210 | */
211 |
212 | template, /* 1 */
213 | [hidden] {
214 | display: none;
215 | }
216 |
217 | /* Links
218 | ========================================================================== */
219 |
220 | /**
221 | * 1. Remove the gray background on active links in IE 10.
222 | * 2. Remove gaps in links underline in iOS 8+ and Safari 8+.
223 | */
224 |
225 | a {
226 | background-color: transparent; /* 1 */
227 | -webkit-text-decoration-skip: objects; /* 2 */
228 | }
229 |
230 | /**
231 | * Remove the outline on focused links when they are also active or hovered
232 | * in all browsers (opinionated).
233 | */
234 |
235 | a:active,
236 | a:hover {
237 | outline-width: 0;
238 | }
239 |
240 | /* Text-level semantics
241 | ========================================================================== */
242 |
243 | /**
244 | * 1. Remove the bottom border in Firefox 39-.
245 | * 2. Add the correct text decoration in Chrome, Edge, IE, Opera, and Safari.
246 | */
247 |
248 | abbr[title] {
249 | border-bottom: none; /* 1 */
250 | text-decoration: underline; /* 2 */
251 | text-decoration: underline dotted; /* 2 */
252 | }
253 |
254 | /**
255 | * Prevent the duplicate application of `bolder` by the next rule in Safari 6.
256 | */
257 |
258 | b,
259 | strong {
260 | font-weight: inherit;
261 | }
262 |
263 | /**
264 | * Add the correct font weight in Chrome, Edge, and Safari.
265 | */
266 |
267 | b,
268 | strong {
269 | font-weight: bolder;
270 | }
271 |
272 | /**
273 | * Add the correct font style in Android 4.3-.
274 | */
275 |
276 | dfn {
277 | font-style: italic;
278 | }
279 |
280 | /**
281 | * Correct the font size and margin on `h1` elements within `section` and
282 | * `article` contexts in Chrome, Firefox, and Safari.
283 | */
284 |
285 | h1 {
286 | font-size: 2em;
287 | margin: 0.67em 0;
288 | }
289 |
290 | /**
291 | * Add the correct background and color in IE 9-.
292 | */
293 |
294 | mark {
295 | background-color: #ff0;
296 | color: #000;
297 | }
298 |
299 | /**
300 | * Add the correct font size in all browsers.
301 | */
302 |
303 | small {
304 | font-size: 80%;
305 | }
306 |
307 | /**
308 | * Prevent `sub` and `sup` elements from affecting the line height in
309 | * all browsers.
310 | */
311 |
312 | sub,
313 | sup {
314 | font-size: 75%;
315 | line-height: 0;
316 | position: relative;
317 | vertical-align: baseline;
318 | }
319 |
320 | sub {
321 | bottom: -0.25em;
322 | }
323 |
324 | sup {
325 | top: -0.5em;
326 | }
327 |
328 | /* Embedded content
329 | ========================================================================== */
330 |
331 | /**
332 | * Remove the border on images inside links in IE 10-.
333 | */
334 |
335 | img {
336 | border-style: none;
337 | }
338 |
339 | /**
340 | * Hide the overflow in IE.
341 | */
342 |
343 | svg:not(:root) {
344 | overflow: hidden;
345 | }
346 |
347 | /* Grouping content
348 | ========================================================================== */
349 |
350 | /**
351 | * 1. Correct the inheritance and scaling of font size in all browsers.
352 | * 2. Correct the odd `em` font sizing in all browsers.
353 | */
354 |
355 | code,
356 | kbd,
357 | pre,
358 | samp {
359 | font-family: monospace, monospace; /* 1 */
360 | font-size: 1em; /* 2 */
361 | }
362 |
363 | /**
364 | * Add the correct margin in IE 8.
365 | */
366 |
367 | figure {
368 | margin: 1em 40px;
369 | }
370 |
371 | /**
372 | * 1. Add the correct box sizing in Firefox.
373 | * 2. Show the overflow in Edge and IE.
374 | */
375 |
376 | hr {
377 | box-sizing: content-box; /* 1 */
378 | height: 0; /* 1 */
379 | overflow: visible; /* 2 */
380 | }
381 |
382 | /* Forms
383 | ========================================================================== */
384 |
385 | /**
386 | * 1. Change font properties to `inherit` in all browsers (opinionated).
387 | * 2. Remove the margin in Firefox and Safari.
388 | */
389 |
390 | button,
391 | input,
392 | select,
393 | textarea {
394 | font: inherit; /* 1 */
395 | margin: 0; /* 2 */
396 | }
397 |
398 | /**
399 | * Restore the font weight unset by the previous rule.
400 | */
401 |
402 | optgroup {
403 | font-weight: bold;
404 | }
405 |
406 | /**
407 | * Show the overflow in IE.
408 | * 1. Show the overflow in Edge.
409 | */
410 |
411 | button,
412 | input { /* 1 */
413 | overflow: visible;
414 | }
415 |
416 | /**
417 | * Remove the inheritance of text transform in Edge, Firefox, and IE.
418 | * 1. Remove the inheritance of text transform in Firefox.
419 | */
420 |
421 | button,
422 | select { /* 1 */
423 | text-transform: none;
424 | }
425 |
426 | /**
427 | * 1. Prevent a WebKit bug where (2) destroys native `audio` and `video`
428 | * controls in Android 4.
429 | * 2. Correct the inability to style clickable types in iOS and Safari.
430 | */
431 |
432 | button,
433 | html [type="button"], /* 1 */
434 | [type="reset"],
435 | [type="submit"] {
436 | -webkit-appearance: button; /* 2 */
437 | }
438 |
439 | /**
440 | * Remove the inner border and padding in Firefox.
441 | */
442 |
443 | button::-moz-focus-inner,
444 | [type="button"]::-moz-focus-inner,
445 | [type="reset"]::-moz-focus-inner,
446 | [type="submit"]::-moz-focus-inner {
447 | border-style: none;
448 | padding: 0;
449 | }
450 |
451 | /**
452 | * Restore the focus styles unset by the previous rule.
453 | */
454 |
455 | button:-moz-focusring,
456 | [type="button"]:-moz-focusring,
457 | [type="reset"]:-moz-focusring,
458 | [type="submit"]:-moz-focusring {
459 | outline: 1px dotted ButtonText;
460 | }
461 |
462 | /**
463 | * Change the border, margin, and padding in all browsers (opinionated).
464 | */
465 |
466 | fieldset {
467 | border: 1px solid #c0c0c0;
468 | margin: 0 2px;
469 | padding: 0.35em 0.625em 0.75em;
470 | }
471 |
472 | /**
473 | * 1. Correct the text wrapping in Edge and IE.
474 | * 2. Correct the color inheritance from `fieldset` elements in IE.
475 | * 3. Remove the padding so developers are not caught out when they zero out
476 | * `fieldset` elements in all browsers.
477 | */
478 |
479 | legend {
480 | box-sizing: border-box; /* 1 */
481 | color: inherit; /* 2 */
482 | display: table; /* 1 */
483 | max-width: 100%; /* 1 */
484 | padding: 0; /* 3 */
485 | white-space: normal; /* 1 */
486 | }
487 |
488 | /**
489 | * Remove the default vertical scrollbar in IE.
490 | */
491 |
492 | textarea {
493 | overflow: auto;
494 | }
495 |
496 | /**
497 | * 1. Add the correct box sizing in IE 10-.
498 | * 2. Remove the padding in IE 10-.
499 | */
500 |
501 | [type="checkbox"],
502 | [type="radio"] {
503 | box-sizing: border-box; /* 1 */
504 | padding: 0; /* 2 */
505 | }
506 |
507 | /**
508 | * Correct the cursor style of increment and decrement buttons in Chrome.
509 | */
510 |
511 | [type="number"]::-webkit-inner-spin-button,
512 | [type="number"]::-webkit-outer-spin-button {
513 | height: auto;
514 | }
515 |
516 | /**
517 | * 1. Correct the odd appearance in Chrome and Safari.
518 | * 2. Correct the outline style in Safari.
519 | */
520 |
521 | [type="search"] {
522 | -webkit-appearance: textfield; /* 1 */
523 | outline-offset: -2px; /* 2 */
524 | }
525 |
526 | /**
527 | * Remove the inner padding and cancel buttons in Chrome and Safari on OS X.
528 | */
529 |
530 | [type="search"]::-webkit-search-cancel-button,
531 | [type="search"]::-webkit-search-decoration {
532 | -webkit-appearance: none;
533 | }
534 |
535 | /**
536 | * Correct the text style of placeholders in Chrome, Edge, and Safari.
537 | */
538 |
539 | ::-webkit-input-placeholder {
540 | color: inherit;
541 | opacity: 0.54;
542 | }
543 |
544 | /**
545 | * 1. Correct the inability to style clickable types in iOS and Safari.
546 | * 2. Change font properties to `inherit` in Safari.
547 | */
548 |
549 | ::-webkit-file-upload-button {
550 | -webkit-appearance: button; /* 1 */
551 | font: inherit; /* 2 */
552 | }
553 |
554 |
555 |
556 |
557 | /**
558 | * CUSTOM CSS:
559 | */
560 |
561 | ul,ol {
562 | padding: 0;
563 | margin: 10 0 10px 25px
564 | }
565 |
566 | ul ul, ul ol, ol ol, ol ul {
567 | margin-bottom: 0;
568 | }
569 |
570 | li {
571 | line-height: 20px
572 | }
573 |
574 | * {
575 | box-sizing: border-box;
576 | }
577 |
578 |
579 | body {
580 | font-family: "Helvetica", "Open Sans","Helvetica Neue",Helvetica,Arial,sans-serif;
581 | /* bodyFontSize */
582 | font-size: 14px;
583 | margin: 0px;
584 | line-height: 20px;
585 | /* backgroundColor */
586 | background-color: #2b303b;
587 |
588 | /* colorText */
589 | color: #c0c5ce;
590 | padding: 40px;
591 | padding-top: 50px;
592 | }
593 |
594 | td.module {
595 | font-family: Menlo,Menlo,Consolas,"Courier New",monospace;
596 | /* codeFontSize */
597 | font-size: 13px
598 | }
599 |
600 |
601 | code, pre {
602 | font-family: Menlo,Menlo,Consolas,"Courier New",monospace;
603 | /* codeFontSize */
604 | font-size: 13px;
605 | color: #333;
606 | }
607 |
608 | a {
609 | color: inherit;
610 | /* colorYellow */
611 | text-decoration: none;
612 | -webkit-transition: color 0.1s ease-out;
613 | -moz-transition: color 0.1s ease-out;
614 | -o-transition: color 0.1s ease-out;
615 | transition: color 0.1s ease-out;
616 | }
617 |
618 | a:hover,a:focus {
619 | color: inherit;
620 | /* colorYellowActive */
621 | text-decoration: none;
622 | outline: none;
623 | -webkit-transition: color 0.1s ease-out;
624 | -moz-transition: color 0.1s ease-out;
625 | -o-transition: color 0.1s ease-out;
626 | transition: color 0.1s ease-out;
627 | }
628 |
629 | .typetable {
630 | /* So that top level pre's margin-bottom isn't conflicting */
631 | margin-top: -10px;
632 | }
633 |
634 | pre, .typetable {
635 | border-radius: 0;
636 | border: none;
637 | /* codeFontSize */
638 | font-size: 13px;
639 | }
640 |
641 | .constructor {
642 | /* colorRed */
643 | color: #BF616A;
644 | }
645 |
646 | .keyword {
647 | /* colorKeyword (purple) */
648 | color: #b48ead;
649 | }
650 |
651 | .type {
652 | color: #BF616A;
653 | }
654 |
655 | .string {
656 | color: #91B376;
657 | }
658 |
659 | pre {
660 | display: block;
661 | line-height: 20px;
662 | word-break: break-all;
663 | word-wrap: break-word;
664 | white-space: pre;
665 | white-space: pre-wrap;
666 | }
667 |
668 | pre.prettyprint {
669 | margin-bottom: 20px
670 | }
671 |
672 | code {
673 | white-space: nowrap;
674 | -webkit-border-radius: 0;
675 | -moz-border-radius: 0;
676 | -ms-border-radius: 0;
677 | -o-border-radius: 0;
678 | border-radius: 0
679 | }
680 |
681 | /**
682 | * code.code are typically inline code, in an info section - not code snippets.
683 | */
684 | .info code.code, .param_info code.code {
685 | /* backgroundColorInlineCode */
686 | background-color: #393d48;
687 | border-radius:1px;
688 | padding: 1px 3px 1px 3px;
689 | }
690 |
691 | /* Creates better underline for anything inside an anchor (better than standard
692 | * text decoration) that is inside an info or param_info. */
693 | body > a > *,
694 | p > a > *,
695 | li > a > *,
696 | .info > a > *,
697 | .param_info > a > * {
698 | /* colorFadedText (comment) */
699 | border-bottom: 1px dotted #EBCB8B;
700 | }
701 |
702 | body > a:hover > *,
703 | body > a:focus > *,
704 | p > a:hover > *,
705 | p > a:focus > *,
706 | li > a:hover > *,
707 | li > a:focus > *,
708 | .info > a:hover > *,
709 | .info > a:focus > *,
710 | .param_info > a:hover > *,
711 | .param_info > a:focus > * {
712 | /* colorYellow */
713 | border-bottom: 1px solid #EBCB8B;
714 | }
715 |
716 |
717 | /**
718 | * Anchors appearing in pre or code do not contain more pre or code typically,
719 | * and usually only contain text: which is why we must target their anchor directly.
720 | * Which didn't work when the anchor had a code child (bottom borders do not render)
721 | */
722 | pre > a,
723 | code > a,
724 | .typetable a {
725 | /* colorFadedText (comment) */
726 | border-bottom: 1px dotted #EBCB8B;
727 | }
728 |
729 | pre > a:focus,
730 | pre > a:hover,
731 | code > a:focus,
732 | code > a:hover,
733 | .typetable a:focus,
734 | .typetable a:hover {
735 | /* colorYellow */
736 | border-bottom: 1px solid #EBCB8B;
737 | }
738 |
739 | /**
740 | * For named arguments documentation: Give the named arguments a little pop.
741 | */
742 | .param_info > code.code:nth-child(1) {
743 | /* backgroundColorInlineBorder */
744 | border: 1px solid #474b56;
745 | }
746 |
747 |
748 |
749 | pre code {
750 | color: inherit;
751 | white-space: pre;
752 | white-space: pre-wrap;
753 | background-color: transparent;
754 | border: 0
755 | }
756 |
757 | h1, h2, h3, h4, h5, h6 {
758 | margin: 10px 0;
759 | font-weight: bold;
760 | line-height: 20px;
761 | color: inherit;
762 | text-rendering: optimizelegibility;
763 | }
764 |
765 | h1 {
766 | font-size: 22px;
767 | }
768 |
769 | h2 {
770 | font-size: 20px
771 | }
772 |
773 | h3 {
774 | font-size: 18px
775 | }
776 |
777 | h4 {
778 | font-size: 16px
779 | }
780 |
781 | h5 {
782 | font-size: 14px
783 | }
784 |
785 | /**
786 | * The ocamldoc generator uses these for primary headers:
787 | */
788 | h6 {
789 | font-size: 18px;
790 | }
791 |
792 | /**
793 | * To fix the formatting, we hide all the brs, and add a bunch of space above the h6's.
794 | */
795 | h6 {
796 | margin-top:40px;
797 | }
798 |
799 | /**
800 | * Ocamldoc generator uses .h7 as subheaders
801 | */
802 | .h7 {
803 | /* bodyFontSize */
804 | font-size: 14px;
805 | font-weight: bold;
806 | }
807 |
808 | body > h1 {
809 | /* backgroundColorDark */
810 | background-color: #252932;
811 | margin-right: -40px;
812 | margin-left: -40px;
813 | padding-top: 10px;
814 | padding-left: 20px;
815 | padding-right: 20px;
816 | padding-bottom: 10px;
817 | }
818 |
819 | body > h1:first-of-type {
820 | text-align:right;
821 | position: fixed;
822 | z-index: 90;
823 | left: 0;
824 | right: 0;
825 | margin: 0;
826 | top: 0;
827 | }
828 |
829 | h1 > a {
830 | /* colorRed */
831 | color: #BF616A;
832 | }
833 | h1 > a:active, h1 > a:focus, h1 > a:hover {
834 | /* colorRedActive */
835 | color: #CB6D77;
836 | }
837 |
838 | .navbar {
839 | position: fixed;
840 | left: 0; right: 0;
841 | margin-top: -50px; /* Match body padding */
842 | margin-bottom: 0px;
843 | padding-top: 0px;
844 | padding-left: 20px;
845 | padding-right: 20px;
846 | padding-bottom: 0px;
847 | z-index: 91;
848 | }
849 |
850 |
851 | .navbar > a {
852 | display: inline-block;
853 | font-weight: bold;
854 | color: #999;
855 | text-decoration: none;
856 | padding-top: 14px;
857 | padding-left: 5px;
858 | padding-right: 5px;
859 | height: 40px;
860 | border-bottom: 4px solid;
861 | }
862 |
863 | .navbar > a:nth-child(1n) {
864 | /* colorGreen */
865 | border-bottom: 4px solid #91B376;
866 | }
867 |
868 | .navbar > a:nth-child(2n) {
869 | /* colorRed */
870 | border-bottom: 4px solid #BF616A;
871 | }
872 |
873 | .navbar > a:nth-child(3n) {
874 | /* colorCyan */
875 | border-bottom: 4px solid #96B5B4;
876 | }
877 |
878 | .navbar > a:nth-child(4n) {
879 | border-bottom: 4px solid #cec47f;
880 | }
881 |
882 | .navbar > a:nth-child(5n) {
883 | border-bottom: 4px solid #b58900;
884 | }
885 |
886 |
887 | .navbar a:hover, a:focus {
888 | opacity: 1.0;
889 | text-decoration: none
890 | }
891 |
892 |
893 |
894 | .indextable {
895 | /* backgroundColor */
896 | background-color: #2b303b;
897 | }
898 |
899 | .indextable td {
900 | padding-left: 5px;
901 | padding-right: 5px;
902 | }
903 |
904 | .indexlist {
905 | margin-top: 12px;
906 | }
907 |
908 |
909 | body > .info {
910 | /* backgroundColorPanel */
911 | background-color: #313641;
912 | padding: 20px;
913 | margin-left:20px;
914 | margin-top: 15px;
915 | /* So that the top level pre's 30px margin-top is halfed, but param info's
916 | * are sucked up into the top level .info's */
917 | /* colorFadedText (comment) */
918 | border-left: 5px solid rgba(101,115,126, 0.2);
919 | }
920 |
921 |
922 |
923 | body > .param_info {
924 | /* backgroundColorPanel */
925 | margin-top:1px;
926 | background-color: #313641;
927 | margin-left: 20px;
928 | padding: 15px;
929 | /* colorGreen */
930 | border-left: 5px solid #91B376;
931 | }
932 |
933 | pre + .info, table + .info {
934 | /* margin-bottom:15px; */
935 | }
936 |
937 | /**
938 | * Each module entry should have proper spacing.
939 | */
940 | body > pre {
941 | margin-top: 20px;
942 | margin-bottom: 10px;
943 | margin-left: 0px;
944 | margin-right: 0px;
945 | }
946 |
947 |
948 | .paramstable {
949 | /* codeFontSize */
950 | font-size: 13px;
951 | }
952 |
953 |
954 | .info.module.top {
955 | /* By default, free floating text in the top info will have a lighter weight and larger size.
956 | * Then inner
tags style will then bring it back down to standard weight/size, but the first
957 | * free floating text which describes the module is *not* in a p tag so will have this nicer look */
958 | font-size: 18px;
959 | /* colorText */
960 | color: #c0c5ce;
961 | /* margin-left: -50px; */
962 | /* margin-right: -50px; */
963 | margin-left: 0px;
964 | }
965 |
966 | /* The first block of text */
967 | .info.module.top > *:nth-child(1) {
968 | font-size: 16px;
969 | font-weight: 300;
970 | padding-bottom: 10px;
971 | }
972 |
973 | .info.module.top > code, .info.module.top > .code,
974 | .info.module.top > p > .code {
975 | /* background-color: #545454; */
976 | }
977 |
978 |
979 | .info.module.top + hr {
980 | position: relative;
981 | font-weight: normal;
982 | font-size: 24px;
983 | border:none;
984 | line-height: normal;
985 | display: inline-block;
986 | margin-top: 0;
987 | margin-left: -25px;
988 | color: white;
989 | white-space: nowrap;
990 | -webkit-transition: all 0.1s ease-out;
991 | -moz-transition: all 0.1s ease-out;
992 | -o-transition: all 0.1s ease-out;
993 | transition: all 0.1s ease-out;
994 | opacity: 0.8;
995 | -webkit-backface-visibility: hidden
996 | }
997 | /**
998 | * See the Set documentation for why we need this:
999 | */
1000 | .info > .codepre > code > br {
1001 | display:none;
1002 | }
1003 | .codepre {
1004 | padding:10px;
1005 | /* backgroundColorInlineCode */
1006 | background-color: #393d48;
1007 | }
1008 | .info > .codepre > .code {
1009 | font-weight: normal;
1010 | /* No background color on inner code lines/elements because the outer .codepre has
1011 | * provided the background color. */
1012 | background-color: transparent;
1013 | }
1014 |
1015 | /* .info.module.top + hr:after { */
1016 | /* content: " "; */
1017 | /* display: block; */
1018 | /* border-top: 4px solid #3d3d3b; */
1019 | /* opacity: 0.8; */
1020 | /* width: 0; */
1021 | /* height: 0; */
1022 | /* position: absolute; */
1023 | /* bottom: -4px; */
1024 | /* border-left: 5px solid transparent; */
1025 | /* left: 0 */
1026 | /* } */
1027 | /* */
1028 | /* hr:after { */
1029 | /* border-top-color: #b9221f; */
1030 | /* } */
1031 |
1032 |
1033 | pre, code, .code {
1034 | /* colorText */
1035 | color: #c0c5ce;
1036 | }
1037 |
1038 | pre, code, .code, pre *, code *, .code * {
1039 | /* codeFontSize */
1040 | font-size: 13px;
1041 | }
1042 |
1043 | .typefieldcomment {
1044 | visibility:hidden;
1045 | }
1046 |
1047 | .typefieldcomment > .info {
1048 | visibility: visible;
1049 | }
1050 |
1051 | pre {
1052 | padding-left: 0px; /* More to fix the trailing } */
1053 | }
1054 |
1055 | .info, b, ol *, ul *, p {
1056 | /* bodyFontSize */
1057 | font-size: 14px;
1058 | }
1059 |
1060 |
1061 | .navbar {
1062 | font-size: 18px;
1063 | }
1064 |
1065 | /* hacks for documents with .lstframe code listings */
1066 | td[bgcolor=white] {
1067 | /* removes white blocks next to certain code listings */
1068 | display: none;
1069 | }
1070 |
1071 | .lstframe {
1072 | background-color: transparent !important;
1073 | }
1074 |
--------------------------------------------------------------------------------