diff --git a/components.js b/components.js index 4b934ad4f7..48ab6dca46 100644 --- a/components.js +++ b/components.js @@ -202,6 +202,11 @@ var components = { "require": "clike", "owner": "simonreynolds7" }, + "flow": { + "title": "Flow", + "require": "javascript", + "owner": "Golmote" + }, "fortran": { "title": "Fortran", "owner": "Golmote" diff --git a/components/prism-flow.js b/components/prism-flow.js new file mode 100644 index 0000000000..7e42ed3c8b --- /dev/null +++ b/components/prism-flow.js @@ -0,0 +1,34 @@ +(function (Prism) { + Prism.languages.flow = Prism.languages.extend('javascript', {}); + + Prism.languages.insertBefore('flow', 'keyword', { + 'type': [ + { + pattern: /\b(?:[Nn]umber|[Ss]tring|[Bb]oolean|Function|any|mixed|null|void)\b/, + alias: 'tag' + } + ] + }); + Prism.languages.flow['function-variable'].pattern = /[_$a-zA-Z\xA0-\uFFFF][_$a-zA-Z0-9\xA0-\uFFFF]*(?=\s*=\s*(?:function\b|(?:\([^()]*\)(?:\s*:\s*\w+)?|[_$a-zA-Z\xA0-\uFFFF][_$a-zA-Z0-9\xA0-\uFFFF]*)\s*=>))/i; + + Prism.languages.insertBefore('flow', 'operator', { + 'flow-punctuation': { + pattern: /\{\||\|\}/, + alias: 'punctuation' + } + }); + + if (Prism.util.type(Prism.languages.flow.keyword) !== 'Array') { + Prism.languages.flow.keyword = [Prism.languages.flow.keyword]; + } + Prism.languages.flow.keyword.unshift( + { + pattern: /(^|[^$]\b)(?:type|opaque|declare|Class)\b(?!\$)/, + lookbehind: true + }, + { + pattern: /(^|[^$]\B)\$(?:await|Diff|Exact|Keys|ObjMap|PropertyType|Shape|Record|Supertype|Subtype|Enum)\b(?!\$)/, + lookbehind: true + } + ); +}(Prism)); \ No newline at end of file diff --git a/components/prism-flow.min.js b/components/prism-flow.min.js new file mode 100644 index 0000000000..b966631088 --- /dev/null +++ b/components/prism-flow.min.js @@ -0,0 +1 @@ +!function(a){a.languages.flow=a.languages.extend("javascript",{}),a.languages.insertBefore("flow","keyword",{type:[{pattern:/\b(?:[Nn]umber|[Ss]tring|[Bb]oolean|Function|any|mixed|null|void)\b/,alias:"tag"}]}),a.languages.flow["function-variable"].pattern=/[_$a-zA-Z\xA0-\uFFFF][_$a-zA-Z0-9\xA0-\uFFFF]*(?=\s*=\s*(?:function\b|(?:\([^()]*\)(?:\s*:\s*\w+)?|[_$a-zA-Z\xA0-\uFFFF][_$a-zA-Z0-9\xA0-\uFFFF]*)\s*=>))/i,a.languages.insertBefore("flow","operator",{"flow-punctuation":{pattern:/\{\||\|\}/,alias:"punctuation"}}),"Array"!==a.util.type(a.languages.flow.keyword)&&(a.languages.flow.keyword=[a.languages.flow.keyword]),a.languages.flow.keyword.unshift({pattern:/(^|[^$]\b)(?:type|opaque|declare|Class)\b(?!\$)/,lookbehind:!0},{pattern:/(^|[^$]\B)\$(?:await|Diff|Exact|Keys|ObjMap|PropertyType|Shape|Record|Supertype|Subtype|Enum)\b(?!\$)/,lookbehind:!0})}(Prism); \ No newline at end of file diff --git a/examples/prism-flow.html b/examples/prism-flow.html new file mode 100644 index 0000000000..2742d214e4 --- /dev/null +++ b/examples/prism-flow.html @@ -0,0 +1,21 @@ +
To use this language, use the class "language-flow".
+ +function method(x: number, y: string, z: boolean) {}
+function stringifyBasicValue(value: string | number) {}
+function add(one: any, two: any): number {
+ return one + two;
+}
+
+const bar: number = 2;
+var barVar: number = 2;
+let barLet: number = 2;
+let isOneOf: number | boolean | string = foo;
+
+type UnionAlias = 1 | 2 | 3;
+opaque type ID = string;
+declare opaque type PositiveNumber: number;
+type Country = $Keys<typeof countries>;
+type RequiredProps = $Diff<Props, DefaultProps>;
\ No newline at end of file
diff --git a/plugins/autoloader/prism-autoloader.js b/plugins/autoloader/prism-autoloader.js
index 0a21d3d564..41f405d550 100644
--- a/plugins/autoloader/prism-autoloader.js
+++ b/plugins/autoloader/prism-autoloader.js
@@ -4,7 +4,7 @@
}
// The dependencies map is built automatically with gulp
- var lang_dependencies = /*languages_placeholder[*/{"javascript":"clike","actionscript":"javascript","arduino":"cpp","aspnet":"markup","bison":"c","c":"clike","csharp":"clike","cpp":"c","coffeescript":"javascript","crystal":"ruby","css-extras":"css","d":"clike","dart":"clike","django":"markup","fsharp":"clike","glsl":"clike","go":"clike","groovy":"clike","haml":"ruby","handlebars":"markup","haxe":"clike","java":"clike","jolie":"clike","kotlin":"clike","less":"css","markdown":"markup","n4js":"javascript","nginx":"clike","objectivec":"c","opencl":"cpp","parser":"markup","php":"clike","php-extras":"php","processing":"clike","protobuf":"clike","pug":"javascript","qore":"clike","jsx":["markup","javascript"],"reason":"clike","ruby":"clike","sass":"css","scss":"css","scala":"java","smarty":"markup","swift":"clike","textile":"markup","twig":"markup","typescript":"javascript","vbnet":"basic","wiki":"markup"}/*]*/;
+ var lang_dependencies = /*languages_placeholder[*/{"javascript":"clike","actionscript":"javascript","arduino":"cpp","aspnet":"markup","bison":"c","c":"clike","csharp":"clike","cpp":"c","coffeescript":"javascript","crystal":"ruby","css-extras":"css","d":"clike","dart":"clike","django":"markup","fsharp":"clike","flow":"javascript","glsl":"clike","go":"clike","groovy":"clike","haml":"ruby","handlebars":"markup","haxe":"clike","java":"clike","jolie":"clike","kotlin":"clike","less":"css","markdown":"markup","n4js":"javascript","nginx":"clike","objectivec":"c","opencl":"cpp","parser":"markup","php":"clike","php-extras":"php","processing":"clike","protobuf":"clike","pug":"javascript","qore":"clike","jsx":["markup","javascript"],"reason":"clike","ruby":"clike","sass":"css","scss":"css","scala":"java","smarty":"markup","swift":"clike","textile":"markup","twig":"markup","typescript":"javascript","vbnet":"basic","wiki":"markup"}/*]*/;
var lang_data = {};
diff --git a/plugins/autoloader/prism-autoloader.min.js b/plugins/autoloader/prism-autoloader.min.js
index 2ce34e2b2e..bc8ce703cd 100644
--- a/plugins/autoloader/prism-autoloader.min.js
+++ b/plugins/autoloader/prism-autoloader.min.js
@@ -1 +1 @@
-!function(){if("undefined"!=typeof self&&self.Prism&&self.document&&document.createElement){var e={javascript:"clike",actionscript:"javascript",arduino:"cpp",aspnet:"markup",bison:"c",c:"clike",csharp:"clike",cpp:"c",coffeescript:"javascript",crystal:"ruby","css-extras":"css",d:"clike",dart:"clike",django:"markup",fsharp:"clike",glsl:"clike",go:"clike",groovy:"clike",haml:"ruby",handlebars:"markup",haxe:"clike",java:"clike",jolie:"clike",kotlin:"clike",less:"css",markdown:"markup",n4js:"javascript",nginx:"clike",objectivec:"c",opencl:"cpp",parser:"markup",php:"clike","php-extras":"php",processing:"clike",protobuf:"clike",pug:"javascript",qore:"clike",jsx:["markup","javascript"],reason:"clike",ruby:"clike",sass:"css",scss:"css",scala:"java",smarty:"markup",swift:"clike",textile:"markup",twig:"markup",typescript:"javascript",vbnet:"basic",wiki:"markup"},c={},a="none",s=Prism.plugins.autoloader={languages_path:"components/",use_minified:!0},n=function(e,c,a){var s=document.createElement("script");s.src=e,s.async=!0,s.onload=function(){document.body.removeChild(s),c&&c()},s.onerror=function(){document.body.removeChild(s),a&&a()},document.body.appendChild(s)},r=function(e){return s.languages_path+"prism-"+e+(s.use_minified?".min":"")+".js"},i=function(e,a){var s=c[e];s||(s=c[e]={});var n=a.getAttribute("data-dependencies");!n&&a.parentNode&&"pre"===a.parentNode.tagName.toLowerCase()&&(n=a.parentNode.getAttribute("data-dependencies")),n=n?n.split(/\s*,\s*/g):[],t(n,function(){l(e,function(){Prism.highlightElement(a)})})},t=function(e,c,a){"string"==typeof e&&(e=[e]);var s=0,n=e.length,r=function(){n>s?l(e[s],function(){s++,r()},function(){a&&a(e[s])}):s===n&&c&&c(e)};r()},l=function(a,s,i){var l=function(){var e=!1;a.indexOf("!")>=0&&(e=!0,a=a.replace("!",""));var t=c[a];if(t||(t=c[a]={}),s&&(t.success_callbacks||(t.success_callbacks=[]),t.success_callbacks.push(s)),i&&(t.error_callbacks||(t.error_callbacks=[]),t.error_callbacks.push(i)),!e&&Prism.languages[a])o(a);else if(!e&&t.error)u(a);else if(e||!t.loading){t.loading=!0;var l=r(a);n(l,function(){t.loading=!1,o(a)},function(){t.loading=!1,t.error=!0,u(a)})}},p=e[a];p&&p.length?t(p,l):l()},o=function(e){c[e]&&c[e].success_callbacks&&c[e].success_callbacks.length&&c[e].success_callbacks.forEach(function(c){c(e)})},u=function(e){c[e]&&c[e].error_callbacks&&c[e].error_callbacks.length&&c[e].error_callbacks.forEach(function(c){c(e)})};Prism.hooks.add("complete",function(e){e.element&&e.language&&!e.grammar&&e.language!==a&&i(e.language,e.element)})}}();
\ No newline at end of file
+!function(){if("undefined"!=typeof self&&self.Prism&&self.document&&document.createElement){var e={javascript:"clike",actionscript:"javascript",arduino:"cpp",aspnet:"markup",bison:"c",c:"clike",csharp:"clike",cpp:"c",coffeescript:"javascript",crystal:"ruby","css-extras":"css",d:"clike",dart:"clike",django:"markup",fsharp:"clike",flow:"javascript",glsl:"clike",go:"clike",groovy:"clike",haml:"ruby",handlebars:"markup",haxe:"clike",java:"clike",jolie:"clike",kotlin:"clike",less:"css",markdown:"markup",n4js:"javascript",nginx:"clike",objectivec:"c",opencl:"cpp",parser:"markup",php:"clike","php-extras":"php",processing:"clike",protobuf:"clike",pug:"javascript",qore:"clike",jsx:["markup","javascript"],reason:"clike",ruby:"clike",sass:"css",scss:"css",scala:"java",smarty:"markup",swift:"clike",textile:"markup",twig:"markup",typescript:"javascript",vbnet:"basic",wiki:"markup"},c={},a="none",s=Prism.plugins.autoloader={languages_path:"components/",use_minified:!0},n=function(e,c,a){var s=document.createElement("script");s.src=e,s.async=!0,s.onload=function(){document.body.removeChild(s),c&&c()},s.onerror=function(){document.body.removeChild(s),a&&a()},document.body.appendChild(s)},r=function(e){return s.languages_path+"prism-"+e+(s.use_minified?".min":"")+".js"},i=function(e,a){var s=c[e];s||(s=c[e]={});var n=a.getAttribute("data-dependencies");!n&&a.parentNode&&"pre"===a.parentNode.tagName.toLowerCase()&&(n=a.parentNode.getAttribute("data-dependencies")),n=n?n.split(/\s*,\s*/g):[],t(n,function(){l(e,function(){Prism.highlightElement(a)})})},t=function(e,c,a){"string"==typeof e&&(e=[e]);var s=0,n=e.length,r=function(){n>s?l(e[s],function(){s++,r()},function(){a&&a(e[s])}):s===n&&c&&c(e)};r()},l=function(a,s,i){var l=function(){var e=!1;a.indexOf("!")>=0&&(e=!0,a=a.replace("!",""));var t=c[a];if(t||(t=c[a]={}),s&&(t.success_callbacks||(t.success_callbacks=[]),t.success_callbacks.push(s)),i&&(t.error_callbacks||(t.error_callbacks=[]),t.error_callbacks.push(i)),!e&&Prism.languages[a])o(a);else if(!e&&t.error)u(a);else if(e||!t.loading){t.loading=!0;var l=r(a);n(l,function(){t.loading=!1,o(a)},function(){t.loading=!1,t.error=!0,u(a)})}},p=e[a];p&&p.length?t(p,l):l()},o=function(e){c[e]&&c[e].success_callbacks&&c[e].success_callbacks.length&&c[e].success_callbacks.forEach(function(c){c(e)})},u=function(e){c[e]&&c[e].error_callbacks&&c[e].error_callbacks.length&&c[e].error_callbacks.forEach(function(c){c(e)})};Prism.hooks.add("complete",function(e){e.element&&e.language&&!e.grammar&&e.language!==a&&i(e.language,e.element)})}}();
\ No newline at end of file
diff --git a/tests/languages/flow/flow-punctuation_feature.test b/tests/languages/flow/flow-punctuation_feature.test
new file mode 100644
index 0000000000..ba0c900515
--- /dev/null
+++ b/tests/languages/flow/flow-punctuation_feature.test
@@ -0,0 +1,12 @@
+{| foo : string |}
+
+----------------------------------------------------
+
+[
+ ["flow-punctuation", "{|"], " foo ", ["punctuation", ":"],
+ ["type", "string"], ["flow-punctuation", "|}"]
+]
+
+----------------------------------------------------
+
+Checks for Flow specific punctuation.
\ No newline at end of file
diff --git a/tests/languages/flow/function-variable_feature.test b/tests/languages/flow/function-variable_feature.test
new file mode 100644
index 0000000000..cda25c97bf
--- /dev/null
+++ b/tests/languages/flow/function-variable_feature.test
@@ -0,0 +1,20 @@
+foo = (a: number) : number => {}
+bar = () : string => {}
+
+----------------------------------------------------
+
+[
+ ["function-variable", "foo"], ["operator", "="],
+ ["punctuation", "("], "a", ["punctuation", ":"],
+ ["type", "number"], ["punctuation", ")"],
+ ["punctuation", ":"], ["type", "number"],
+ ["operator", "=>"], ["punctuation", "{"], ["punctuation", "}"],
+ ["function-variable", "bar"], ["operator", "="],
+ ["punctuation", "("], ["punctuation", ")"],
+ ["punctuation", ":"], ["type", "string"],
+ ["operator", "=>"], ["punctuation", "{"], ["punctuation", "}"]
+]
+
+----------------------------------------------------
+
+Checks for function variables containing types.
\ No newline at end of file
diff --git a/tests/languages/flow/keyword_feature.test b/tests/languages/flow/keyword_feature.test
new file mode 100644
index 0000000000..fc1ca2accb
--- /dev/null
+++ b/tests/languages/flow/keyword_feature.test
@@ -0,0 +1,39 @@
+type
+opaque
+declare
+Class
+$await
+$Diff
+$Exact
+$Keys
+$ObjMap
+$PropertyType
+$Shape
+$Record
+$Supertype
+$Subtype
+$Enum
+
+----------------------------------------------------
+
+[
+ ["keyword", "type"],
+ ["keyword", "opaque"],
+ ["keyword", "declare"],
+ ["keyword", "Class"],
+ ["keyword", "$await"],
+ ["keyword", "$Diff"],
+ ["keyword", "$Exact"],
+ ["keyword", "$Keys"],
+ ["keyword", "$ObjMap"],
+ ["keyword", "$PropertyType"],
+ ["keyword", "$Shape"],
+ ["keyword", "$Record"],
+ ["keyword", "$Supertype"],
+ ["keyword", "$Subtype"],
+ ["keyword", "$Enum"]
+]
+
+----------------------------------------------------
+
+Checks for keywords.
\ No newline at end of file
diff --git a/tests/languages/flow/type_feature.test b/tests/languages/flow/type_feature.test
new file mode 100644
index 0000000000..53827c351a
--- /dev/null
+++ b/tests/languages/flow/type_feature.test
@@ -0,0 +1,31 @@
+Number
+number
+String
+string
+Boolean
+boolean
+Function
+any
+mixed
+null
+void
+
+----------------------------------------------------
+
+[
+ ["type", "Number"],
+ ["type", "number"],
+ ["type", "String"],
+ ["type", "string"],
+ ["type", "Boolean"],
+ ["type", "boolean"],
+ ["type", "Function"],
+ ["type", "any"],
+ ["type", "mixed"],
+ ["type", "null"],
+ ["type", "void"]
+]
+
+----------------------------------------------------
+
+Checks for types.
\ No newline at end of file