From e8815e7bb2faefea760faccd3462b9f7298f3042 Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Thu, 22 May 2008 22:41:23 -0500 Subject: [PATCH 01/39] Moving validators to their own vocabulary --- extra/validators/validators-tests.factor | 70 +++++++++++ extra/validators/validators.factor | 142 +++++++++++++++++++++++ 2 files changed, 212 insertions(+) create mode 100644 extra/validators/validators-tests.factor create mode 100644 extra/validators/validators.factor diff --git a/extra/validators/validators-tests.factor b/extra/validators/validators-tests.factor new file mode 100644 index 0000000000..6ed0e0363a --- /dev/null +++ b/extra/validators/validators-tests.factor @@ -0,0 +1,70 @@ +IN: validators.tests +USING: kernel sequences tools.test validators accessors ; + +[ "foo" v-number ] must-fail +[ 123 ] [ "123" v-number ] unit-test + +[ "slava@factorcode.org" ] [ + "slava@factorcode.org" v-email +] unit-test + +[ "slava+foo@factorcode.org" ] [ + "slava+foo@factorcode.org" v-email +] unit-test + +[ "slava@factorcode.o" v-email ] +[ "invalid e-mail" = ] must-fail-with + +[ "sla@@factorcode.o" v-email ] +[ "invalid e-mail" = ] must-fail-with + +[ "slava@factorcodeorg" v-email ] +[ "invalid e-mail" = ] must-fail-with + +[ "http://www.factorcode.org" ] +[ "http://www.factorcode.org" v-url ] unit-test + +[ "http:/www.factorcode.org" v-url ] +[ "invalid URL" = ] must-fail-with + +[ 14 V{ } ] [ + [ + "14" "age" [ drop v-number 13 v-min-value 100 v-max-value ] validate + ] with-validation +] unit-test + +[ f t ] [ + [ + "140" "age" [ drop v-number 13 v-min-value 100 v-max-value ] validate + ] with-validation first + [ first "age" = ] + [ second validation-error? ] + [ second value>> "140" = ] + tri and and +] unit-test + +TUPLE: person name age ; + +person { + { "name" [ v-required ] } + { "age" [ v-number 13 v-min-value 100 v-max-value ] } +} define-validators + +[ 14 V{ } ] [ + [ + person new dup + { { "age" "14" } } + deposit-slots + age>> + ] with-validation +] unit-test + +[ t ] [ + [ + { { "age" "" } } required-values + ] with-validation first + [ first "age" = ] + [ second validation-error? ] + [ second message>> "required" = ] + tri and and +] unit-test diff --git a/extra/validators/validators.factor b/extra/validators/validators.factor new file mode 100644 index 0000000000..23bda8cb6c --- /dev/null +++ b/extra/validators/validators.factor @@ -0,0 +1,142 @@ +! Copyright (C) 2006, 2008 Slava Pestov +! See http://factorcode.org/license.txt for BSD license. +USING: kernel continuations sequences math namespaces sets +math.parser assocs regexp fry unicode.categories sequences +arrays hashtables words combinators mirrors classes quotations ; +IN: validators + +: v-default ( str def -- str ) + over empty? spin ? ; + +: v-required ( str -- str ) + dup empty? [ "required" throw ] when ; + +: v-optional ( str quot -- str ) + over empty? [ 2drop f ] [ call ] if ; inline + +: v-min-length ( str n -- str ) + over length over < [ + [ "must be at least " % # " characters" % ] "" make + throw + ] [ + drop + ] if ; + +: v-max-length ( str n -- str ) + over length over > [ + [ "must be no more than " % # " characters" % ] "" make + throw + ] [ + drop + ] if ; + +: v-number ( str -- n ) + dup string>number [ ] [ "must be a number" throw ] ?if ; + +: v-integer ( n -- n ) + dup integer? [ "must be an integer" throw ] unless ; + +: v-min-value ( x n -- x ) + 2dup < [ + [ "must be at least " % # ] "" make throw + ] [ + drop + ] if ; + +: v-max-value ( x n -- x ) + 2dup > [ + [ "must be no more than " % # ] "" make throw + ] [ + drop + ] if ; + +: v-regexp ( str what regexp -- str ) + >r over r> matches? + [ drop ] [ "invalid " prepend throw ] if ; + +: v-email ( str -- str ) + #! From http://www.regular-expressions.info/email.html + "e-mail" + R' [A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}'i + v-regexp ; + +: v-url ( str -- str ) + "URL" + R' (ftp|http|https)://(\w+:?\w*@)?(\S+)(:[0-9]+)?(/|/([\w#!:.?+=&%@!\-/]))?' + v-regexp ; + +: v-captcha ( str -- str ) + dup empty? [ "must remain blank" throw ] unless ; + +: v-one-line ( str -- str ) + dup "\r\n" intersect empty? + [ "must be a single line" throw ] unless ; + +: v-one-word ( str -- str ) + dup [ alpha? ] all? + [ "must be a single word" throw ] unless ; + +SYMBOL: validation-messages + +: with-validation ( quot -- messages ) + V{ } clone [ + validation-messages rot with-variable + ] keep ; inline + +: (validation-message) ( obj -- ) + validation-messages get push ; + +: (validation-message-for) ( obj name -- ) + swap 2array (validation-message) ; + +TUPLE: validation-message message ; + +C: validation-message + +: validation-message ( string -- ) + (validation-message) ; + +: validation-message-for ( string name -- ) + [ ] dip (validation-message-for) ; + +TUPLE: validation-error value message ; + +C: validation-error + +: validation-error ( reason -- ) + f (validation-message) ; + +: validation-error-for ( reason value name -- ) + [ ] dip (validation-message-for) ; + +: validation-failed? ( -- ? ) + validation-messages get [ + dup pair? [ second ] when validation-error? + ] contains? ; + +: define-validators ( class validators -- ) + >hashtable "validators" set-word-prop ; + +: validate ( value name quot -- result ) + [ swap validation-error-for f ] recover ; inline + +: validate-value ( value name validators -- result ) + '[ + , at { + { [ dup pair? ] [ first ] } + { [ dup quotation? ] [ ] } + } cond call + ] validate ; + +: required-values ( assoc -- ) + [ swap [ drop v-required ] validate drop ] assoc-each ; + +: validate-values ( assoc validators -- assoc' ) + '[ over , validate-value ] assoc-map ; + +: deposit-values ( destination assoc validators -- ) + validate-values update ; + +: deposit-slots ( tuple assoc -- ) + [ [ ] [ class "validators" word-prop ] bi ] dip + swap deposit-values ; From 3ee56c3a68eea3570d0cb0cb61df30ff84ba2831 Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Thu, 22 May 2008 22:41:48 -0500 Subject: [PATCH 02/39] Add extract-keys word --- core/assocs/assocs-tests.factor | 14 ++++++++++++++ core/assocs/assocs.factor | 3 +++ .../standard/engines/predicate/predicate.factor | 3 +-- core/inference/class/class.factor | 12 ++++++------ 4 files changed, 24 insertions(+), 8 deletions(-) diff --git a/core/assocs/assocs-tests.factor b/core/assocs/assocs-tests.factor index 30f2ec23c4..43a1bac82d 100755 --- a/core/assocs/assocs-tests.factor +++ b/core/assocs/assocs-tests.factor @@ -104,3 +104,17 @@ unit-test 2drop ] { } make ] unit-test + +[ + H{ + { "bangers" "mash" } + { "fries" "onion rings" } + } +] [ + { "bangers" "fries" } H{ + { "fish" "chips" } + { "bangers" "mash" } + { "fries" "onion rings" } + { "nachos" "cheese" } + } extract-keys +] unit-test diff --git a/core/assocs/assocs.factor b/core/assocs/assocs.factor index 92db38573a..6b0798f2e3 100755 --- a/core/assocs/assocs.factor +++ b/core/assocs/assocs.factor @@ -150,6 +150,9 @@ M: assoc assoc-clone-like ( assoc exemplar -- newassoc ) : map>assoc ( seq quot exemplar -- assoc ) >r [ 2array ] compose { } map-as r> assoc-like ; inline +: extract-keys ( seq assoc -- subassoc ) + [ [ dupd at ] curry ] keep map>assoc ; + M: assoc >alist [ 2array ] { } assoc>map ; : value-at ( value assoc -- key/f ) diff --git a/core/generic/standard/engines/predicate/predicate.factor b/core/generic/standard/engines/predicate/predicate.factor index b1bfc659df..9c810592a0 100644 --- a/core/generic/standard/engines/predicate/predicate.factor +++ b/core/generic/standard/engines/predicate/predicate.factor @@ -22,8 +22,7 @@ C: predicate-dispatch-engine } cond ; : sort-methods ( assoc -- assoc' ) - [ keys sort-classes ] - [ [ dupd at ] curry ] bi { } map>assoc ; + >alist [ keys sort-classes ] keep extract-keys ; M: predicate-dispatch-engine engine>quot methods>> clone diff --git a/core/inference/class/class.factor b/core/inference/class/class.factor index 933710aaca..dc632425fe 100755 --- a/core/inference/class/class.factor +++ b/core/inference/class/class.factor @@ -152,16 +152,16 @@ M: pair apply-constraint M: pair constraint-satisfied? first constraint-satisfied? ; -: extract-keys ( seq assoc -- newassoc ) - [ dupd at ] curry H{ } map>assoc [ nip ] assoc-filter f assoc-like ; +: valid-keys ( seq assoc -- newassoc ) + extract-keys [ nip ] assoc-filter f assoc-like ; : annotate-node ( node -- ) #! Annotate the node with the currently-inferred set of #! value classes. dup node-values { - [ value-intervals get extract-keys >>intervals ] - [ value-classes get extract-keys >>classes ] - [ value-literals get extract-keys >>literals ] + [ value-intervals get valid-keys >>intervals ] + [ value-classes get valid-keys >>classes ] + [ value-literals get valid-keys >>literals ] [ 2drop ] } cleave ; @@ -330,7 +330,7 @@ M: #return infer-classes-around [ ] [ node-input-classes ] [ in-d>> [ value-class* ] map ] tri classes= not [ fixed-point? off - [ in-d>> value-classes get extract-keys ] keep + [ in-d>> value-classes get valid-keys ] keep set-node-classes ] [ drop ] if ] [ call-next-method ] if From f693c69c406a96ef03c33b821be9805d3bc51179 Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Fri, 23 May 2008 17:33:31 -0500 Subject: [PATCH 03/39] Move HTML components to html.components, refactor --- extra/html/components/components-tests.factor | 145 +++++++++++++++++ extra/html/components/components.factor | 150 ++++++++++++++++++ extra/html/elements/elements-tests.factor | 7 +- extra/html/elements/elements.factor | 66 +++++--- extra/html/{ => streams}/authors.txt | 0 .../streams-tests.factor} | 7 +- .../{html.factor => streams/streams.factor} | 73 +-------- extra/html/{ => streams}/summary.txt | 0 extra/html/{ => streams}/tags.txt | 0 extra/html/stylesheet.css | 4 - extra/validators/validators.factor | 1 + 11 files changed, 345 insertions(+), 108 deletions(-) create mode 100644 extra/html/components/components-tests.factor create mode 100644 extra/html/components/components.factor rename extra/html/{ => streams}/authors.txt (100%) rename extra/html/{html-tests.factor => streams/streams-tests.factor} (89%) rename extra/html/{html.factor => streams/streams.factor} (71%) rename extra/html/{ => streams}/summary.txt (100%) rename extra/html/{ => streams}/tags.txt (100%) delete mode 100644 extra/html/stylesheet.css diff --git a/extra/html/components/components-tests.factor b/extra/html/components/components-tests.factor new file mode 100644 index 0000000000..6ecd2b0fa6 --- /dev/null +++ b/extra/html/components/components-tests.factor @@ -0,0 +1,145 @@ +IN: html.components.tests +USING: html.components tools.test kernel io.streams.string +io.streams.null accessors ; + +[ ] [ blank-values ] unit-test + +[ ] [ 3 "hi" set-value ] unit-test + +[ 3 ] [ "hi" value ] unit-test + +TUPLE: color red green blue ; + +[ ] [ 1 2 3 color boa from-tuple ] unit-test + +[ 1 ] [ "red" value ] unit-test + +[ ] [ "jimmy" "red" set-value ] unit-test + +[ "123.5" ] [ 123.5 object>string ] unit-test + +[ "jimmy" ] [ + [ + "red" label render + ] with-string-writer +] unit-test + +[ ] [ "" "red" set-value ] unit-test + +[ "<jimmy>" ] [ + [ + "red" label render + ] with-string-writer +] unit-test + +[ "" ] [ + [ + "red" hidden render + ] with-string-writer +] unit-test + +[ ] [ "'jimmy'" "red" set-value ] unit-test + +[ "" ] [ + [ + "red" 5 >>size render + ] with-string-writer +] unit-test + +[ "" ] [ + [ + "red" 5 >>size render + ] with-string-writer +] unit-test + +[ ] [ + [ + "green" ; + +! Choice +TUPLE: choice size choices multiple ; + +: ( -- choice ) + choice new ; + +: render-option ( text selected? -- ) + ; + +: render-options ( options selected -- ) + '[ dup , member? render-option ] each ; + +M: choice render* + ; + +! Checkboxes +TUPLE: checkbox label ; + +: ( -- checkbox ) + checkbox new ; + +M: checkbox render* + + label>> escape-string write + ; + +! Link components +GENERIC: link-title ( obj -- string ) +GENERIC: link-href ( obj -- url ) + +SINGLETON: link + +M: link render* + 2drop + + link-title object>string escape-string write + ; + +! HTML component +SINGLETON: html + +M: html render* 2drop write ; diff --git a/extra/html/elements/elements-tests.factor b/extra/html/elements/elements-tests.factor index aa6a017540..1178deab38 100644 --- a/extra/html/elements/elements-tests.factor +++ b/extra/html/elements/elements-tests.factor @@ -1,8 +1,5 @@ IN: html.elements.tests -USING: tools.test html html.elements io.streams.string ; - -: make-html-string - [ with-html-stream ] with-string-writer ; +USING: tools.test html.elements io.streams.string ; [ "" ] -[ [ ] make-html-string ] unit-test +[ [ ] with-string-writer ] unit-test diff --git a/extra/html/elements/elements.factor b/extra/html/elements/elements.factor index 49782fa305..e5377cedf8 100644 --- a/extra/html/elements/elements.factor +++ b/extra/html/elements/elements.factor @@ -57,6 +57,8 @@ SYMBOL: html : print-html ( str -- ) write-html "\n" write-html ; +<< + : html-word ( name def effect -- ) #! Define 'word creating' word to allow #! dynamically creating words. @@ -137,30 +139,46 @@ SYMBOL: html dup "=" prepend swap [ write-attr ] curry attribute-effect html-word ; +! Define some closed HTML tags [ - ! Define some closed HTML tags - [ - "h1" "h2" "h3" "h4" "h5" "h6" "h7" "h8" "h9" - "ol" "li" "form" "a" "p" "html" "head" "body" "title" - "b" "i" "ul" "table" "tbody" "tr" "td" "th" "pre" "textarea" - "script" "div" "span" "select" "option" "style" "input" - ] [ define-closed-html-word ] each + "h1" "h2" "h3" "h4" "h5" "h6" "h7" "h8" "h9" + "ol" "li" "form" "a" "p" "html" "head" "body" "title" + "b" "i" "ul" "table" "tbody" "tr" "td" "th" "pre" "textarea" + "script" "div" "span" "select" "option" "style" "input" +] [ define-closed-html-word ] each - ! Define some open HTML tags - [ - "input" - "br" - "link" - "img" - ] [ define-open-html-word ] each +! Define some open HTML tags +[ + "input" + "br" + "link" + "img" +] [ define-open-html-word ] each - ! Define some attributes - [ - "method" "action" "type" "value" "name" - "size" "href" "class" "border" "rows" "cols" - "id" "onclick" "style" "valign" "accesskey" - "src" "language" "colspan" "onchange" "rel" - "width" "selected" "onsubmit" "xmlns" "lang" "xml:lang" - "media" "title" "multiple" - ] [ define-attribute-word ] each -] with-compilation-unit +! Define some attributes +[ + "method" "action" "type" "value" "name" + "size" "href" "class" "border" "rows" "cols" + "id" "onclick" "style" "valign" "accesskey" + "src" "language" "colspan" "onchange" "rel" + "width" "selected" "onsubmit" "xmlns" "lang" "xml:lang" + "media" "title" "multiple" +] [ define-attribute-word ] each + +>> + +: xhtml-preamble ( -- ) + "" write-html + "" write-html ; + +: simple-page ( title quot -- ) + #! Call the quotation, with all output going to the + #! body of an html page with the given title. + xhtml-preamble + + swap write + call + ; + +: render-error ( message -- ) + escape-string write ; diff --git a/extra/html/authors.txt b/extra/html/streams/authors.txt similarity index 100% rename from extra/html/authors.txt rename to extra/html/streams/authors.txt diff --git a/extra/html/html-tests.factor b/extra/html/streams/streams-tests.factor similarity index 89% rename from extra/html/html-tests.factor rename to extra/html/streams/streams-tests.factor index 9f1ce6b689..2084c7db18 100644 --- a/extra/html/html-tests.factor +++ b/extra/html/streams/streams-tests.factor @@ -1,6 +1,7 @@ -USING: html http io io.streams.string io.styles kernel -namespaces tools.test xml.writer sbufs sequences html.private ; -IN: html.tests +USING: html.streams html.streams.private +io io.streams.string io.styles kernel +namespaces tools.test xml.writer sbufs sequences ; +IN: html.streams.tests : make-html-string [ with-html-stream ] with-string-writer ; inline diff --git a/extra/html/html.factor b/extra/html/streams/streams.factor similarity index 71% rename from extra/html/html.factor rename to extra/html/streams/streams.factor index 71862b0d01..b35f383bdc 100755 --- a/extra/html/html.factor +++ b/extra/html/streams/streams.factor @@ -4,7 +4,7 @@ USING: generic assocs help http io io.styles io.files continuations io.streams.string kernel math math.order math.parser namespaces quotations assocs sequences strings words html.elements xml.entities sbufs continuations destructors ; -IN: html +IN: html.streams GENERIC: browser-link-href ( presented -- href ) @@ -192,76 +192,5 @@ M: html-stream make-cell-stream ( style stream -- stream' ) M: html-stream stream-nl ( stream -- ) dup test-last-div? [ drop ] [ [
] with-output-stream* ] if ; -! Utilities : with-html-stream ( quot -- ) output-stream get swap with-output-stream* ; inline - -: xhtml-preamble - "" write-html - "" write-html ; - -: html-document ( body-quot head-quot -- ) - #! head-quot is called to produce output to go - #! in the html head portion of the document. - #! body-quot is called to produce output to go - #! in the html body portion of the document. - xhtml-preamble - - call - call - ; - -: default-css ( -- ) - ; - -: simple-html-document ( title quot -- ) - swap [ - write - default-css - ] html-document ; - -: vertical-layout ( list -- ) - #! Given a list of HTML components, arrange them vertically. - - [ ] each -
call
; - -: horizontal-layout ( list -- ) - #! Given a list of HTML components, arrange them horizontally. - - [ ] each -
call
; - -: button ( label -- ) - #! Output an HTML submit button with the given label. - ; - -: paragraph ( str -- ) - #! Output the string as an html paragraph -

write

; - -: simple-page ( title quot -- ) - #! Call the quotation, with all output going to the - #! body of an html page with the given title. - - swap write - call - ; - -: styled-page ( title stylesheet-quot quot -- ) - #! Call the quotation, with all output going to the - #! body of an html page with the given title. stylesheet-quot - #! is called to generate the required stylesheet. - - - rot write - swap call - - call - ; - -: render-error ( message -- ) - escape-string write ; diff --git a/extra/html/summary.txt b/extra/html/streams/summary.txt similarity index 100% rename from extra/html/summary.txt rename to extra/html/streams/summary.txt diff --git a/extra/html/tags.txt b/extra/html/streams/tags.txt similarity index 100% rename from extra/html/tags.txt rename to extra/html/streams/tags.txt diff --git a/extra/html/stylesheet.css b/extra/html/stylesheet.css deleted file mode 100644 index a1afce7c9f..0000000000 --- a/extra/html/stylesheet.css +++ /dev/null @@ -1,4 +0,0 @@ -a:link { text-decoration: none; color: black; } -a:visited { text-decoration: none; color: black; } -a:active { text-decoration: none; color: black; } -a:hover { text-decoration: underline; color: black; } diff --git a/extra/validators/validators.factor b/extra/validators/validators.factor index 23bda8cb6c..9d6c4bed90 100644 --- a/extra/validators/validators.factor +++ b/extra/validators/validators.factor @@ -56,6 +56,7 @@ IN: validators : v-email ( str -- str ) #! From http://www.regular-expressions.info/email.html + 60 v-max-length "e-mail" R' [A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}'i v-regexp ; From a251556024462da9e36135558f256649c4102b75 Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Fri, 23 May 2008 17:33:57 -0500 Subject: [PATCH 04/39] Add failing unit tests --- core/classes/classes-tests.factor | 9 +++++++++ core/parser/parser-tests.factor | 7 +++++++ 2 files changed, 16 insertions(+) diff --git a/core/classes/classes-tests.factor b/core/classes/classes-tests.factor index bb9fbd0167..8d20da78b5 100755 --- a/core/classes/classes-tests.factor +++ b/core/classes/classes-tests.factor @@ -160,3 +160,12 @@ TUPLE: flat-mx-2-1 ; INSTANCE: flat-mx-2-1 flat-mx-2 [ t ] [ 3 number instance? ] unit-test [ f ] [ 3 null instance? ] unit-test [ t ] [ "hi" \ hi-tag instance? ] unit-test + +! Regression +GENERIC: method-forget-test +TUPLE: method-forget-class ; +M: method-forget-class method-forget-test ; + +[ f ] [ \ method-forget-test "methods" assoc-empty? ] unit-test +[ ] [ [ \ method-forget-class forget ] with-compilation-unit ] unit-test +[ t ] [ \ method-forget-test "methods" assoc-empty? ] unit-test diff --git a/core/parser/parser-tests.factor b/core/parser/parser-tests.factor index 3df9dc9cb2..6f31b0ad7c 100755 --- a/core/parser/parser-tests.factor +++ b/core/parser/parser-tests.factor @@ -460,3 +460,10 @@ must-fail-with "change-combination" "parser.tests" lookup "methods" word-prop assoc-size ] unit-test + +[ [ ] ] [ + 2 [ + "IN: classes.tests DEFER: twice-fails FORGET: twice-fails MIXIN: twice-fails" + "twice-fails-test" parse-stream + ] times +] unit-test From cee6ab6770f6aa90dbb085ba08c21e1139a0a8cf Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Fri, 23 May 2008 17:45:00 -0500 Subject: [PATCH 05/39] Add unit test to prevent future screwups --- core/prettyprint/prettyprint-tests.factor | 2 ++ 1 file changed, 2 insertions(+) diff --git a/core/prettyprint/prettyprint-tests.factor b/core/prettyprint/prettyprint-tests.factor index ed6b2f3c3c..f5ec263f11 100755 --- a/core/prettyprint/prettyprint-tests.factor +++ b/core/prettyprint/prettyprint-tests.factor @@ -342,3 +342,5 @@ INTERSECTION: intersection-see-test sequence number ; [ ] [ \ compose see ] unit-test [ ] [ \ curry see ] unit-test + +[ "POSTPONE: [" ] [ \ [ unparse ] unit-test From 3a6532a9f89e91a04389d885119de255780cc4f9 Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Fri, 23 May 2008 17:45:14 -0500 Subject: [PATCH 06/39] Update html.streams usages --- extra/farkup/farkup-tests.factor | 2 +- extra/farkup/farkup.factor | 10 ++++------ extra/xmode/code2html/code2html.factor | 8 ++++---- 3 files changed, 9 insertions(+), 11 deletions(-) diff --git a/extra/farkup/farkup-tests.factor b/extra/farkup/farkup-tests.factor index 7176486f8e..4d235a054c 100755 --- a/extra/farkup/farkup-tests.factor +++ b/extra/farkup/farkup-tests.factor @@ -54,7 +54,7 @@ IN: farkup.tests [ "

=

foo

" ] [ "===foo==" convert-farkup ] unit-test [ "

foo

=

" ] [ "=foo==" convert-farkup ] unit-test -[ "
int main()
" ] +[ "
int main()\n
" ] [ "[c{int main()}]" convert-farkup ] unit-test [ "

" ] [ "[[image:lol.jpg]]" convert-farkup ] unit-test diff --git a/extra/farkup/farkup.factor b/extra/farkup/farkup.factor index 15b7b4b72c..860fdba3af 100755 --- a/extra/farkup/farkup.factor +++ b/extra/farkup/farkup.factor @@ -2,7 +2,7 @@ ! See http://factorcode.org/license.txt for BSD license. USING: arrays io io.styles kernel memoize namespaces peg sequences strings html.elements xml.entities xmode.code2html -splitting io.streams.string html peg.parsers html.elements +splitting io.streams.string peg.parsers sequences.deep unicode.categories ; IN: farkup @@ -56,11 +56,9 @@ MEMO: eq ( -- parser ) : render-code ( string mode -- string' ) >r string-lines r> [ - [ - H{ { wrap-margin f } } [ - htmlize-lines - ] with-nesting - ] with-html-stream +
+            htmlize-lines
+        
] with-string-writer ; : check-url ( href -- href' ) diff --git a/extra/xmode/code2html/code2html.factor b/extra/xmode/code2html/code2html.factor index 3977f4277c..a9384ad861 100755 --- a/extra/xmode/code2html/code2html.factor +++ b/extra/xmode/code2html/code2html.factor @@ -1,12 +1,12 @@ USING: xmode.tokens xmode.marker xmode.catalog kernel html html.elements io io.files sequences words io.encodings.utf8 -namespaces ; +namespaces xml.entities ; IN: xmode.code2html : htmlize-tokens ( tokens -- ) [ dup token-str swap token-id [ - write + escape-string write ] [ write ] if* @@ -21,7 +21,7 @@ IN: xmode.code2html : default-stylesheet ( -- ) ; : htmlize-stream ( path stream -- ) @@ -29,7 +29,7 @@ IN: xmode.code2html default-stylesheet - dup write + dup escape-string write

From 23c0d0fc9324f91e449d096429248fcb432dce5b Mon Sep 17 00:00:00 2001
From: Slava Pestov 
Date: Fri, 23 May 2008 17:45:33 -0500
Subject: [PATCH 07/39] Another html.streasm usage

---
 extra/http/server/server.factor | 14 ++++++++------
 1 file changed, 8 insertions(+), 6 deletions(-)

diff --git a/extra/http/server/server.factor b/extra/http/server/server.factor
index 4e561220f9..c1684c4ed2 100755
--- a/extra/http/server/server.factor
+++ b/extra/http/server/server.factor
@@ -1,10 +1,10 @@
 ! Copyright (C) 2003, 2008 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: assocs kernel namespaces io io.timeouts strings splitting
-threads sequences prettyprint io.server logging calendar
-http html html.elements accessors math.parser combinators.lib
+threads sequences prettyprint io.server logging calendar http
+html.streams html.elements accessors math.parser combinators.lib
 tools.vocabs debugger continuations random combinators
-destructors io.encodings.8-bit fry classes words ;
+destructors io.encodings.8-bit fry classes words math ;
 IN: http.server
 
 ! path is a sequence of path component strings
@@ -274,9 +274,11 @@ SYMBOL: exit-continuation
     ] with-destructors ;
 
 : httpd ( port -- )
-    internet-server "http.server"
-    latin1 [ handle-client ] with-server ;
+    dup integer? [ internet-server ] when
+    "http.server" latin1
+    [ handle-client ] with-server ;
 
-: httpd-main ( -- ) 8888 httpd ;
+: httpd-main ( -- )
+    8888 httpd ;
 
 MAIN: httpd-main

From 8327449a65a95f95139cf3bd8eeeeddf637e1a72 Mon Sep 17 00:00:00 2001
From: Slava Pestov 
Date: Fri, 23 May 2008 19:16:21 -0500
Subject: [PATCH 08/39] Move templates to html vocabulary

---
 extra/html/components/components-tests.factor | 10 ++-
 extra/html/components/components.factor       |  8 +-
 .../templates}/chloe/chloe-tests.factor       | 10 +--
 .../templates}/chloe/chloe.factor             | 78 ++++++++++-------
 .../templates}/chloe/test/test1.xml           |  0
 .../templates}/chloe/test/test2.xml           |  0
 .../templates}/chloe/test/test3-aux.xml       |  0
 .../templates}/chloe/test/test3.xml           |  0
 .../templates}/chloe/test/test4.xml           |  2 +-
 .../templates}/chloe/test/test5.xml           |  2 +-
 .../templates}/chloe/test/test6.xml           |  2 +-
 .../templates}/chloe/test/test7.xml           |  2 +-
 .../templates}/fhtml/authors.txt              |  0
 .../templates}/fhtml/fhtml-tests.factor       |  6 +-
 .../templates}/fhtml/fhtml.factor             | 43 +++-------
 .../templates}/fhtml/test/bug.fhtml           |  0
 .../templates}/fhtml/test/bug.html            |  0
 .../templates}/fhtml/test/example.fhtml       |  0
 .../templates}/fhtml/test/example.html        |  0
 .../templates}/fhtml/test/stack.fhtml         |  0
 .../templates}/fhtml/test/stack.html          |  0
 extra/html/templates/templates.factor         | 85 +++++++++++++++++++
 .../http/server/templating/templating.factor  | 27 ------
 extra/validators/validators.factor            |  7 +-
 24 files changed, 169 insertions(+), 113 deletions(-)
 rename extra/{http/server/templating => html/templates}/chloe/chloe-tests.factor (84%)
 rename extra/{http/server/templating => html/templates}/chloe/chloe.factor (80%)
 rename extra/{http/server/templating => html/templates}/chloe/test/test1.xml (100%)
 rename extra/{http/server/templating => html/templates}/chloe/test/test2.xml (100%)
 rename extra/{http/server/templating => html/templates}/chloe/test/test3-aux.xml (100%)
 rename extra/{http/server/templating => html/templates}/chloe/test/test3.xml (100%)
 rename extra/{http/server/templating => html/templates}/chloe/test/test4.xml (62%)
 rename extra/{http/server/templating => html/templates}/chloe/test/test5.xml (62%)
 rename extra/{http/server/templating => html/templates}/chloe/test/test6.xml (62%)
 rename extra/{http/server/templating => html/templates}/chloe/test/test7.xml (62%)
 rename extra/{http/server/templating => html/templates}/fhtml/authors.txt (100%)
 rename extra/{http/server/templating => html/templates}/fhtml/fhtml-tests.factor (74%)
 rename extra/{http/server/templating => html/templates}/fhtml/fhtml.factor (62%)
 rename extra/{http/server/templating => html/templates}/fhtml/test/bug.fhtml (100%)
 rename extra/{http/server/templating => html/templates}/fhtml/test/bug.html (100%)
 rename extra/{http/server/templating => html/templates}/fhtml/test/example.fhtml (100%)
 rename extra/{http/server/templating => html/templates}/fhtml/test/example.html (100%)
 rename extra/{http/server/templating => html/templates}/fhtml/test/stack.fhtml (100%)
 rename extra/{http/server/templating => html/templates}/fhtml/test/stack.html (100%)
 create mode 100644 extra/html/templates/templates.factor
 delete mode 100644 extra/http/server/templating/templating.factor

diff --git a/extra/html/components/components-tests.factor b/extra/html/components/components-tests.factor
index 6ecd2b0fa6..0bd5410a3b 100644
--- a/extra/html/components/components-tests.factor
+++ b/extra/html/components/components-tests.factor
@@ -60,7 +60,7 @@ TUPLE: color red green blue ;
 
 [ ] [
     [
-        "green"  ;
 
 ! Choice
-TUPLE: choice size choices multiple ;
+TUPLE: choice size multiple choices ;
 
 :  ( -- choice )
     choice new ;
@@ -112,7 +112,7 @@ M: choice render*
         dup size>> [ number>string =size ] when*
         dup multiple>> [ "true" =multiple ] when
     select>
-        [ choices>> ] [ multiple>> ] bi
+        [ choices>> value ] [ multiple>> ] bi
         [ swap ] [ swap 1array ] if
         render-options
      ;
diff --git a/extra/http/server/templating/chloe/chloe-tests.factor b/extra/html/templates/chloe/chloe-tests.factor
similarity index 84%
rename from extra/http/server/templating/chloe/chloe-tests.factor
rename to extra/html/templates/chloe/chloe-tests.factor
index 61f72a2f14..3c52153eee 100644
--- a/extra/http/server/templating/chloe/chloe-tests.factor
+++ b/extra/html/templates/chloe/chloe-tests.factor
@@ -1,8 +1,8 @@
-USING: http.server.templating http.server.templating.chloe
-http.server.components http.server.boilerplate tools.test
-io.streams.string kernel sequences ascii boxes namespaces xml
+USING: html.templates html.templates.chloe
+tools.test io.streams.string kernel sequences ascii boxes
+namespaces xml
 splitting ;
-IN: http.server.templating.chloe.tests
+IN: html.templates.chloe.tests
 
 [ f ] [ f parse-query-attr ] unit-test
 
@@ -26,7 +26,7 @@ IN: http.server.templating.chloe.tests
     "?>" split1 nip ; inline
 
 : test-template ( name -- template )
-    "resource:extra/http/server/templating/chloe/test/"
+    "resource:extra/html/templates/chloe/test/"
     swap
     ".xml" 3append  ;
 
diff --git a/extra/http/server/templating/chloe/chloe.factor b/extra/html/templates/chloe/chloe.factor
similarity index 80%
rename from extra/http/server/templating/chloe/chloe.factor
rename to extra/html/templates/chloe/chloe.factor
index c3d93f5909..a01d424eb9 100644
--- a/extra/http/server/templating/chloe/chloe.factor
+++ b/extra/html/templates/chloe/chloe.factor
@@ -3,13 +3,14 @@
 USING: accessors kernel sequences combinators kernel namespaces
 classes.tuple assocs splitting words arrays memoize
 io io.files io.encodings.utf8 io.streams.string
-unicode.case tuple-syntax html html.elements
+unicode.case tuple-syntax mirrors fry
 multiline xml xml.data xml.writer xml.utilities
+html.elements
+html.components
 http.server
 http.server.auth
 http.server.flows
 http.server.actions
-http.server.components
 http.server.sessions
 http.server.templating
 http.server.boilerplate ;
@@ -52,8 +53,11 @@ MEMO: chloe-name ( string -- name )
 : optional-attr ( tag name -- value )
     chloe-name swap at ;
 
+: process-tag-children ( tag -- )
+    [ process-template ] each ;
+
 : children>string ( tag -- string )
-    [ [ process-template ] each ] with-string-writer ;
+    [ process-tag-children ] with-string-writer ;
 
 : title-tag ( tag -- )
     children>string set-title ;
@@ -89,18 +93,6 @@ MEMO: chloe-name ( string -- name )
         atom-feed get value>> second write
     ] if ;
 
-: component-attr ( tag -- name )
-    "component" required-attr ;
-
-: view-tag ( tag -- )
-    component-attr component render-view ;
-
-: edit-tag ( tag -- )
-    component-attr component render-edit ;
-
-: summary-tag ( tag -- )
-    component-attr component render-summary ;
-
 : parse-query-attr ( string -- assoc )
     dup empty?
     [ drop f ] [ "," split [ dup value ] H{ } map>assoc ] if ;
@@ -133,9 +125,6 @@ MEMO: chloe-name ( string -- name )
         a>
     ] with-scope ;
 
-: process-tag-children ( tag -- )
-    [ process-template ] each ;
-
 : a-tag ( tag -- )
     [ a-start-tag ]
     [ process-tag-children ]
@@ -156,7 +145,7 @@ MEMO: chloe-name ( string -- name )
             form>
         ] [
             hidden-form-field
-            "for" optional-attr [ component render-edit ] when*
+            "for" optional-attr [ hidden render ] when*
         ] bi
     ] with-scope ;
 
@@ -180,9 +169,9 @@ STRING: button-tag-markup
 : button-tag ( tag -- )
     button-tag-markup string>xml delegate
     {
-        [ >r tag-attrs chloe-attrs-only r> add-tag-attrs ]
-        [ >r tag-attrs non-chloe-attrs-only r> "button" tag-named add-tag-attrs ]
-        [ >r children>string 1array r> "button" tag-named set-tag-children ]
+        [ [ tag-attrs chloe-attrs-only ] dip add-tag-attrs ]
+        [ [ tag-attrs non-chloe-attrs-only ] dip "button" tag-named add-tag-attrs ]
+        [ [ children>string 1array ] dip "button" tag-named set-tag-children ]
         [ nip ]
     } 2cleave process-chloe-tag ;
 
@@ -211,27 +200,58 @@ STRING: button-tag-markup
 : error-message-tag ( tag -- )
     children>string render-error ;
 
+: validation-messages-tag ( tag -- )
+    drop render-validation-messages ;
+
+: singleton-component-tag ( tag class -- )
+    [ "name" required-attr ] dip render ;
+
+: attrs>slots ( tag tuple -- )
+    [ attrs>> ] [  ] bi* '[ swap tag>> , set-at ] assoc-each ;
+
+: tuple-component-tag ( tag class -- )
+    [ drop "name" required-attr ]
+    [ new [ attrs>slots ] keep ]
+    2bi render ;
+
 : process-chloe-tag ( tag -- )
     dup name-tag {
-        { "chloe" [ [ process-template ] each ] }
+        { "chloe" [ process-tag-children ] }
+
+        ! HTML head
         { "title" [ title-tag ] }
         { "write-title" [ write-title-tag ] }
         { "style" [ style-tag ] }
         { "write-style" [ write-style-tag ] }
         { "atom" [ atom-tag ] }
         { "write-atom" [ write-atom-tag ] }
-        { "view" [ view-tag ] }
-        { "edit" [ edit-tag ] }
-        { "summary" [ summary-tag ] }
+
+        ! HTML elements
         { "a" [ a-tag ] }
-        { "form" [ form-tag ] }
         { "button" [ button-tag ] }
+
+        ! Components
+        { "label" [ label singleton-component-tag ] }
+        { "link" [ link singleton-component-tag ] }
+        { "html" [ html singleton-component-tag ] }
+
+        ! Forms
+        { "form" [ form-tag ] }
         { "error-message" [ error-message-tag ] }
-        { "validation-message" [ drop render-validation-message ] }
+        { "validation-messages" [ validation-messages-tag ] }
+        { "hidden" [ hidden singleton-component-tag ] }
+        { "field" [ field tuple-component-tag ] }
+        { "password" [ password tuple-component-tag ] }
+        { "textarea" [ textarea tuple-component-tag ] }
+        { "choice" [ choice tuple-component-tag ] }
+        { "checkbox" [ checkbox tuple-component-tag ] }
+
+        ! Control flow
         { "if" [ if-tag ] }
         { "comment" [ drop ] }
         { "call-next-template" [ drop call-next-template ] }
-        [ "Unknown chloe tag: " swap append throw ]
+
+        [ "Unknown chloe tag: " prepend throw ]
     } case ;
 
 : process-tag ( tag -- )
diff --git a/extra/http/server/templating/chloe/test/test1.xml b/extra/html/templates/chloe/test/test1.xml
similarity index 100%
rename from extra/http/server/templating/chloe/test/test1.xml
rename to extra/html/templates/chloe/test/test1.xml
diff --git a/extra/http/server/templating/chloe/test/test2.xml b/extra/html/templates/chloe/test/test2.xml
similarity index 100%
rename from extra/http/server/templating/chloe/test/test2.xml
rename to extra/html/templates/chloe/test/test2.xml
diff --git a/extra/http/server/templating/chloe/test/test3-aux.xml b/extra/html/templates/chloe/test/test3-aux.xml
similarity index 100%
rename from extra/http/server/templating/chloe/test/test3-aux.xml
rename to extra/html/templates/chloe/test/test3-aux.xml
diff --git a/extra/http/server/templating/chloe/test/test3.xml b/extra/html/templates/chloe/test/test3.xml
similarity index 100%
rename from extra/http/server/templating/chloe/test/test3.xml
rename to extra/html/templates/chloe/test/test3.xml
diff --git a/extra/http/server/templating/chloe/test/test4.xml b/extra/html/templates/chloe/test/test4.xml
similarity index 62%
rename from extra/http/server/templating/chloe/test/test4.xml
rename to extra/html/templates/chloe/test/test4.xml
index dd9b232d73..55612360a5 100644
--- a/extra/http/server/templating/chloe/test/test4.xml
+++ b/extra/html/templates/chloe/test/test4.xml
@@ -2,7 +2,7 @@
 
 
 
-	
+	
 		True
 	
 
diff --git a/extra/http/server/templating/chloe/test/test5.xml b/extra/html/templates/chloe/test/test5.xml
similarity index 62%
rename from extra/http/server/templating/chloe/test/test5.xml
rename to extra/html/templates/chloe/test/test5.xml
index 3bd39e45bd..edcbe8f3b1 100644
--- a/extra/http/server/templating/chloe/test/test5.xml
+++ b/extra/html/templates/chloe/test/test5.xml
@@ -2,7 +2,7 @@
 
 
 
-	
+	
 		True
 	
 
diff --git a/extra/http/server/templating/chloe/test/test6.xml b/extra/html/templates/chloe/test/test6.xml
similarity index 62%
rename from extra/http/server/templating/chloe/test/test6.xml
rename to extra/html/templates/chloe/test/test6.xml
index 56234a5f0d..b3f649333f 100644
--- a/extra/http/server/templating/chloe/test/test6.xml
+++ b/extra/html/templates/chloe/test/test6.xml
@@ -2,7 +2,7 @@
 
 
 
-	
+	
 		True
 	
 
diff --git a/extra/http/server/templating/chloe/test/test7.xml b/extra/html/templates/chloe/test/test7.xml
similarity index 62%
rename from extra/http/server/templating/chloe/test/test7.xml
rename to extra/html/templates/chloe/test/test7.xml
index a4f8e06e7d..338595e556 100644
--- a/extra/http/server/templating/chloe/test/test7.xml
+++ b/extra/html/templates/chloe/test/test7.xml
@@ -2,7 +2,7 @@
 
 
 
-	
+	
 		True
 	
 
diff --git a/extra/http/server/templating/fhtml/authors.txt b/extra/html/templates/fhtml/authors.txt
similarity index 100%
rename from extra/http/server/templating/fhtml/authors.txt
rename to extra/html/templates/fhtml/authors.txt
diff --git a/extra/http/server/templating/fhtml/fhtml-tests.factor b/extra/html/templates/fhtml/fhtml-tests.factor
similarity index 74%
rename from extra/http/server/templating/fhtml/fhtml-tests.factor
rename to extra/html/templates/fhtml/fhtml-tests.factor
index 42bec43570..43ea28fa55 100755
--- a/extra/http/server/templating/fhtml/fhtml-tests.factor
+++ b/extra/html/templates/fhtml/fhtml-tests.factor
@@ -1,10 +1,10 @@
 USING: io io.files io.streams.string io.encodings.utf8
-http.server.templating http.server.templating.fhtml kernel
+html.templates html.templates.fhtml kernel
 tools.test sequences parser ;
-IN: http.server.templating.fhtml.tests
+IN: html.templates.fhtml.tests
 
 : test-template ( path -- ? )
-    "resource:extra/http/server/templating/fhtml/test/"
+    "resource:extra/html/templates/fhtml/test/"
     prepend
     [
         ".fhtml" append  [ call-template ] with-string-writer
diff --git a/extra/http/server/templating/fhtml/fhtml.factor b/extra/html/templates/fhtml/fhtml.factor
similarity index 62%
rename from extra/http/server/templating/fhtml/fhtml.factor
rename to extra/html/templates/fhtml/fhtml.factor
index 2cc053a0ca..74e5c37ef1 100755
--- a/extra/http/server/templating/fhtml/fhtml.factor
+++ b/extra/html/templates/fhtml/fhtml.factor
@@ -4,12 +4,10 @@
 USING: continuations sequences kernel namespaces debugger
 combinators math quotations generic strings splitting
 accessors assocs fry
-parser io io.files io.streams.string io.encodings.utf8 source-files
-html html.elements
-http.server.static http.server http.server.templating ;
-IN: http.server.templating.fhtml
-
-: templating-vocab ( -- vocab-name ) "http.server.templating.fhtml" ;
+parser io io.files io.streams.string io.encodings.utf8
+html.elements
+html.templates ;
+IN: html.templates.fhtml
 
 ! We use a custom lexer so that %> ends a token even if not
 ! followed by whitespace
@@ -35,7 +33,7 @@ DEFER: <% delimiter
 : found-<% ( accum lexer col -- accum )
     [
         over line-text>>
-        >r >r column>> r> r> subseq parsed
+        [ column>> ] 2dip subseq parsed
         \ write-html parsed
     ] 2keep 2 + >>column drop ;
 
@@ -62,37 +60,20 @@ DEFER: <% delimiter
 
 : parse-template ( string -- quot )
     [
-        use [ clone ] change
-        templating-vocab use+
+        "quiet" on
+        parser-notes off
+        "html.templates.fhtml" use+
         string-lines parse-template-lines
-    ] with-scope ;
+    ] with-file-vocabs ;
 
-: eval-template ( string -- ) parse-template call ;
-
-: html-error. ( error -- )
-    
 error. 
; +: eval-template ( string -- ) + parse-template call ; TUPLE: fhtml path ; C: fhtml M: fhtml call-template* ( filename -- ) - '[ - , path>> [ - "quiet" on - parser-notes off - templating-vocab use+ - ! so that reload works properly - dup source-file file set - utf8 file-contents - [ eval-template ] [ html-error. drop ] recover - ] with-file-vocabs - ] assert-depth ; - -! file responder integration -: enable-fhtml ( responder -- responder ) - [ serve-template ] - "application/x-factor-server-page" - pick special>> set-at ; + '[ , path>> utf8 file-contents eval-template ] assert-depth ; INSTANCE: fhtml template diff --git a/extra/http/server/templating/fhtml/test/bug.fhtml b/extra/html/templates/fhtml/test/bug.fhtml similarity index 100% rename from extra/http/server/templating/fhtml/test/bug.fhtml rename to extra/html/templates/fhtml/test/bug.fhtml diff --git a/extra/http/server/templating/fhtml/test/bug.html b/extra/html/templates/fhtml/test/bug.html similarity index 100% rename from extra/http/server/templating/fhtml/test/bug.html rename to extra/html/templates/fhtml/test/bug.html diff --git a/extra/http/server/templating/fhtml/test/example.fhtml b/extra/html/templates/fhtml/test/example.fhtml similarity index 100% rename from extra/http/server/templating/fhtml/test/example.fhtml rename to extra/html/templates/fhtml/test/example.fhtml diff --git a/extra/http/server/templating/fhtml/test/example.html b/extra/html/templates/fhtml/test/example.html similarity index 100% rename from extra/http/server/templating/fhtml/test/example.html rename to extra/html/templates/fhtml/test/example.html diff --git a/extra/http/server/templating/fhtml/test/stack.fhtml b/extra/html/templates/fhtml/test/stack.fhtml similarity index 100% rename from extra/http/server/templating/fhtml/test/stack.fhtml rename to extra/html/templates/fhtml/test/stack.fhtml diff --git a/extra/http/server/templating/fhtml/test/stack.html b/extra/html/templates/fhtml/test/stack.html similarity index 100% rename from extra/http/server/templating/fhtml/test/stack.html rename to extra/html/templates/fhtml/test/stack.html diff --git a/extra/html/templates/templates.factor b/extra/html/templates/templates.factor new file mode 100644 index 0000000000..ed26c9b531 --- /dev/null +++ b/extra/html/templates/templates.factor @@ -0,0 +1,85 @@ +! Copyright (C) 2008 Slava Pestov. +! See http://factorcode.org/license.txt for BSD license. +USING: accessors kernel fry io io.encodings.utf8 io.files +debugger prettyprint continuations namespaces boxes sequences +arrays strings html.elements io.streams.string quotations ; +IN: html.templates + +MIXIN: template + +GENERIC: call-template* ( template -- ) + +M: string call-template* write ; + +M: callable call-template* call ; + +M: object call-template* output-stream get stream-copy ; + +ERROR: template-error template error ; + +M: template-error error. + "Error while processing template " write + [ template>> pprint ":" print nl ] + [ error>> error. ] + bi ; + +: call-template ( template -- ) + [ call-template* ] [ template-error ] recover ; + +SYMBOL: title + +: set-title ( string -- ) + title get >box ; + +: write-title ( -- ) + title get value>> write ; + +SYMBOL: style + +: add-style ( string -- ) + "\n" style get push-all + style get push-all ; + +: write-style ( -- ) + style get >string write ; + +SYMBOL: atom-feed + +: set-atom-feed ( title url -- ) + 2array atom-feed get >box ; + +: write-atom-feed ( -- ) + atom-feed get value>> [ + + ] when* ; + +SYMBOL: nested-template? + +SYMBOL: next-template + +: call-next-template ( -- ) + next-template get write-html ; + +M: f call-template* drop call-next-template ; + +: with-boilerplate ( body template -- ) + [ + title get [ title set ] unless + atom-feed get [ atom-feed set ] unless + style get [ SBUF" " clone style set ] unless + + [ + [ + nested-template? on + call-template + ] with-string-writer + next-template set + ] + [ call-template ] + bi* + ] with-scope ; inline + +: template-convert ( template output -- ) + utf8 [ call-template ] with-file-writer ; diff --git a/extra/http/server/templating/templating.factor b/extra/http/server/templating/templating.factor deleted file mode 100644 index 73f6095eae..0000000000 --- a/extra/http/server/templating/templating.factor +++ /dev/null @@ -1,27 +0,0 @@ -USING: accessors kernel fry io io.encodings.utf8 io.files -http http.server debugger prettyprint continuations ; -IN: http.server.templating - -MIXIN: template - -GENERIC: call-template* ( template -- ) - -ERROR: template-error template error ; - -M: template-error error. - "Error while processing template " write - [ template>> pprint ":" print nl ] - [ error>> error. ] - bi ; - -: call-template ( template -- ) - [ call-template* ] [ template-error ] recover ; - -M: template write-response-body* call-template ; - -: template-convert ( template output -- ) - utf8 [ call-template ] with-file-writer ; - -! responder integration -: serve-template ( template -- response ) - '[ , call-template ] ; diff --git a/extra/validators/validators.factor b/extra/validators/validators.factor index 9d6c4bed90..b03cc76444 100644 --- a/extra/validators/validators.factor +++ b/extra/validators/validators.factor @@ -122,12 +122,7 @@ C: validation-error [ swap validation-error-for f ] recover ; inline : validate-value ( value name validators -- result ) - '[ - , at { - { [ dup pair? ] [ first ] } - { [ dup quotation? ] [ ] } - } cond call - ] validate ; + '[ , at call ] validate ; : required-values ( assoc -- ) [ swap [ drop v-required ] validate drop ] assoc-each ; From 73a25d847167120165db844b3d28f8696f4d0328 Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Fri, 23 May 2008 19:22:31 -0500 Subject: [PATCH 09/39] Remove obsolete vocabularies --- extra/http/server/components/code/code.factor | 20 - .../server/components/components-tests.factor | 133 ------ .../http/server/components/components.factor | 401 ------------------ .../server/components/farkup/farkup.factor | 17 - .../components/inspector/inspector.factor | 17 - extra/http/server/components/test/form.fhtml | 1 - extra/http/server/forms/forms.factor | 79 ---- .../server/validators/validators-tests.factor | 29 -- .../http/server/validators/validators.factor | 85 ---- 9 files changed, 782 deletions(-) delete mode 100644 extra/http/server/components/code/code.factor delete mode 100755 extra/http/server/components/components-tests.factor delete mode 100755 extra/http/server/components/components.factor delete mode 100755 extra/http/server/components/farkup/farkup.factor delete mode 100644 extra/http/server/components/inspector/inspector.factor delete mode 100755 extra/http/server/components/test/form.fhtml delete mode 100644 extra/http/server/forms/forms.factor delete mode 100755 extra/http/server/validators/validators-tests.factor delete mode 100755 extra/http/server/validators/validators.factor diff --git a/extra/http/server/components/code/code.factor b/extra/http/server/components/code/code.factor deleted file mode 100644 index 19fc8c5ca8..0000000000 --- a/extra/http/server/components/code/code.factor +++ /dev/null @@ -1,20 +0,0 @@ -! Copyright (C) 2008 Slava Pestov -! See http://factorcode.org/license.txt for BSD license. -USING: splitting kernel io sequences xmode.code2html accessors -http.server.components html xml.entities ; -IN: http.server.components.code - -TUPLE: code-renderer < text-renderer mode ; - -: ( mode -- renderer ) - code-renderer new-text-renderer - swap >>mode ; - -M: code-renderer render-view* - [ - [ string-lines ] [ mode>> value ] bi* htmlize-lines - ] with-html-stream ; - -: ( id mode -- component ) - swap - swap >>renderer ; diff --git a/extra/http/server/components/components-tests.factor b/extra/http/server/components/components-tests.factor deleted file mode 100755 index ff87bb71fb..0000000000 --- a/extra/http/server/components/components-tests.factor +++ /dev/null @@ -1,133 +0,0 @@ -IN: http.server.components.tests -USING: http.server.components http.server.forms -http.server.validators namespaces tools.test kernel accessors -tuple-syntax mirrors -http http.server.actions http.server.templating.fhtml -io.streams.string io.streams.null ; - -validation-failed? off - -[ 3 ] [ "3" "n" validate ] unit-test - -[ 123 ] [ - "" - "n" - 123 >>default - validate -] unit-test - -[ f ] [ validation-failed? get ] unit-test - -[ t ] [ "3x" "n" validate validation-error? ] unit-test - -[ t ] [ validation-failed? get ] unit-test - -[ "" ] [ "" "email" validate ] unit-test - -[ "slava@jedit.org" ] [ "slava@jedit.org" "email" validate ] unit-test - -[ "slava@jedit.org" ] [ - "slava@jedit.org" - "email" - t >>required - validate -] unit-test - -[ t ] [ - "a" - "email" - t >>required - validate validation-error? -] unit-test - -[ t ] [ "a" "email" validate validation-error? ] unit-test - -TUPLE: test-tuple text number more-text ; - -: test-tuple new ; - -: ( -- form ) - "test"
- "resource:extra/http/server/components/test/form.fhtml" >>view-template - "resource:extra/http/server/components/test/form.fhtml" >>edit-template - "text" - t >>required - add-field - "number" - 123 >>default - t >>required - 0 >>min-value - 10 >>max-value - add-field - "more-text" - "hi" >>default - add-field ; - -[ ] [ values set view-form write-response-body drop ] unit-test - -[ ] [ values set edit-form write-response-body drop ] unit-test - -[ TUPLE{ test-tuple number: 123 more-text: "hi" } ] [ - from-tuple - set-defaults - values-tuple -] unit-test - -[ - H{ - { "text" "fdafsa" } - { "number" "xxx" } - { "more-text" "" } - } params set - - H{ } clone values set - - [ t ] [ (validate-form) ] unit-test - - [ "fdafsa" ] [ "text" value ] unit-test - - [ t ] [ "number" value validation-error? ] unit-test -] with-scope - -[ - [ ] [ - "n" - 0 >>min-value - 10 >>max-value - "n" set - ] unit-test - - [ "123" ] [ - "123" "n" get validate value>> - ] unit-test - - [ ] [ "i" "i" set ] unit-test - - [ 3 ] [ - "3" "i" get validate - ] unit-test - - [ t ] [ - "3.9" "i" get validate validation-error? - ] unit-test - - H{ } clone values set - - [ ] [ 3 "i" set-value ] unit-test - - [ "3" ] [ [ "i" get render-view ] with-string-writer ] unit-test - - [ ] [ [ "i" get render-edit ] with-null-stream ] unit-test - - [ ] [ "t" "t" set ] unit-test - - [ ] [ "hello world" "t" set-value ] unit-test - - [ ] [ [ "t" get render-edit ] with-null-stream ] unit-test -] with-scope - -[ t ] [ "wake up sheeple" dup "n" validate = ] unit-test - -[ ] [ "password" "p" set ] unit-test - -[ ] [ "pub-date" "d" set ] unit-test diff --git a/extra/http/server/components/components.factor b/extra/http/server/components/components.factor deleted file mode 100755 index 7f2a5a9ce1..0000000000 --- a/extra/http/server/components/components.factor +++ /dev/null @@ -1,401 +0,0 @@ -! Copyright (C) 2008 Slava Pestov -! See http://factorcode.org/license.txt for BSD license. -USING: accessors namespaces kernel io math.parser assocs classes -words classes.tuple arrays sequences splitting mirrors -hashtables fry locals combinators continuations math -calendar.format html html.elements xml.entities -http.server.validators ; -IN: http.server.components - -! Renderer protocol -GENERIC: render-summary* ( value renderer -- ) -GENERIC: render-view* ( value renderer -- ) -GENERIC: render-edit* ( value id renderer -- ) - -M: object render-summary* render-view* ; - -TUPLE: field type ; - -C: field - -M: field render-view* - drop escape-string write ; - -M: field render-edit* - > =type =name =value input/> ; - -TUPLE: hidden < field ; - -: hidden ( -- renderer ) T{ hidden f "hidden" } ; inline - -! Component protocol -SYMBOL: components - -TUPLE: component id required default renderer ; - -: component ( name -- component ) - dup components get at - [ ] [ "No such component: " prepend throw ] ?if ; - -GENERIC: init ( component -- component ) - -M: component init ; - -GENERIC: validate* ( value component -- result ) -GENERIC: component-string ( value component -- string ) - -SYMBOL: values - -: value values get at ; - -: set-value values get set-at ; - -: blank-values H{ } clone values set ; - -: from-tuple values set ; - -: values-tuple values get mirror-object ; - -: render-view-or-summary ( component -- value renderer ) - [ id>> value ] [ component-string ] [ renderer>> ] tri ; - -: render-view ( component -- ) - render-view-or-summary render-view* ; - -: render-summary ( component -- ) - render-view-or-summary render-summary* ; - -> ] [ renderer>> ] bi render-edit* ; - -: render-edit-error ( component -- ) - [ id>> value ] keep - [ [ value>> ] dip render-edit-string ] - [ drop reason>> render-error ] 2bi ; - -: value-or-default ( component -- value ) - [ id>> value ] [ default>> ] bi or ; - -: render-edit-value ( component -- ) - [ value-or-default ] - [ component-string ] - [ render-edit-string ] - tri ; - -PRIVATE> - -: render-edit ( component -- ) - dup id>> value validation-error? - [ render-edit-error ] [ render-edit-value ] if ; - -: validate ( value component -- result ) - '[ - , - over empty? [ - [ default>> [ v-default ] when* ] - [ required>> [ v-required ] when ] - bi - ] [ validate* ] if - ] with-validator ; - -: new-component ( id class renderer -- component ) - swap new - swap >>renderer - swap >>id - init ; inline - -! String input fields -TUPLE: string < component one-line min-length max-length ; - -: new-string ( id class -- component ) - "text" new-component - t >>one-line ; inline - -: ( id -- component ) - string new-string ; - -M: string validate* - [ one-line>> [ v-one-line ] when ] - [ min-length>> [ v-min-length ] when* ] - [ max-length>> [ v-max-length ] when* ] - tri ; - -M: string component-string - drop ; - -! Username fields -TUPLE: username < string ; - -M: username init - 2 >>min-length - 20 >>max-length ; - -: ( id -- component ) - username new-string ; - -M: username validate* - call-next-method v-one-word ; - -! E-mail fields -TUPLE: email < string ; - -: ( id -- component ) - email new-string - 5 >>min-length - 60 >>max-length ; - -M: email validate* - call-next-method dup empty? [ v-email ] unless ; - -! URL fields -TUPLE: url < string ; - -: ( id -- component ) - url new-string - 5 >>min-length - 60 >>max-length ; - -M: url validate* - call-next-method dup empty? [ v-url ] unless ; - -! Don't send passwords back to the user -TUPLE: password-renderer < field ; - -: password-renderer T{ password-renderer f "password" } ; - -: blank-password >r >r drop "" r> r> ; - -M: password-renderer render-edit* - blank-password call-next-method ; - -! Password fields -TUPLE: password < string ; - -M: password init - 6 >>min-length - 60 >>max-length ; - -: ( id -- component ) - password new-string - password-renderer >>renderer ; - -M: password validate* - call-next-method v-one-word ; - -! Number fields -TUPLE: number < string min-value max-value ; - -: ( id -- component ) - number new-string ; - -M: number validate* - [ v-number ] [ - [ min-value>> [ v-min-value ] when* ] - [ max-value>> [ v-max-value ] when* ] - bi - ] bi* ; - -M: number component-string - drop dup [ number>string ] when ; - -! Integer fields -TUPLE: integer < number ; - -: ( id -- component ) - integer new-string ; - -M: integer validate* - call-next-method v-integer ; - -! Simple captchas -TUPLE: captcha < string ; - -: ( id -- component ) - captcha new-string ; - -M: captcha validate* - drop v-captcha ; - -! Text areas -TUPLE: text-renderer rows cols ; - -: new-text-renderer ( class -- renderer ) - new - 60 >>cols - 20 >>rows ; - -: ( -- renderer ) - text-renderer new-text-renderer ; - -M: text-renderer render-view* - drop escape-string write ; - -M: text-renderer render-edit* - ; - -TUPLE: text < string ; - -: new-text ( id class -- component ) - new-string - f >>one-line - >>renderer ; - -: ( id -- component ) - text new-text ; - -! HTML text component -TUPLE: html-text-renderer < text-renderer ; - -: ( -- renderer ) - html-text-renderer new-text-renderer ; - -M: html-text-renderer render-view* - drop escape-string write ; - -TUPLE: html-text < text ; - -: ( id -- component ) - html-text new-text - >>renderer ; - -! Date component -TUPLE: date < string ; - -: ( id -- component ) - date new-string ; - -M: date component-string - drop timestamp>string ; - -! Link components - -GENERIC: link-title ( obj -- string ) -GENERIC: link-href ( obj -- url ) - -SINGLETON: link-renderer - -M: link-renderer render-view* - drop link-title escape-string write ; - -TUPLE: link < string ; - -: ( id -- component ) - link new-string - link-renderer >>renderer ; - -! List components -SYMBOL: +plain+ -SYMBOL: +ordered+ -SYMBOL: +unordered+ - -TUPLE: list-renderer component type ; - -C: list-renderer - -: render-plain-list ( seq component quot -- ) - '[ , component>> renderer>> @ ] each ; inline - -: render-li-list ( seq component quot -- ) - '[
  • @
  • ] render-plain-list ; inline - -: render-ordered-list ( seq quot component -- ) -
      render-li-list
    ; inline - -: render-unordered-list ( seq quot component -- ) -
      render-li-list
    ; inline - -: render-list ( value renderer quot -- ) - over type>> { - { +plain+ [ render-plain-list ] } - { +ordered+ [ render-ordered-list ] } - { +unordered+ [ render-unordered-list ] } - } case ; inline - -M: list-renderer render-view* - [ render-view* ] render-list ; - -M: list-renderer render-summary* - [ render-summary* ] render-list ; - -TUPLE: list < component ; - -: ( id component type -- list ) - list swap new-component ; - -M: list component-string drop ; - -! Choice -TUPLE: choice-renderer choices ; - -C: choice-renderer - -M: choice-renderer render-view* - drop escape-string write ; - -: render-option ( text selected? -- ) - ; - -: render-options ( options selected -- ) - '[ dup , member? render-option ] each ; - -M: choice-renderer render-edit* - ; - -TUPLE: choice < string ; - -: ( id choices -- component ) - swap choice new-string - swap >>renderer ; - -! Menu -TUPLE: menu-renderer choices size ; - -: ( choices -- renderer ) - 5 menu-renderer boa ; - -M:: menu-renderer render-edit* ( value id renderer -- ) - ; - -TUPLE: menu < string ; - -: ( id choices -- component ) - swap menu new-string - swap >>renderer ; - -! Checkboxes -TUPLE: checkbox-renderer label ; - -C: checkbox-renderer - -M: checkbox-renderer render-edit* - - label>> escape-string write - ; - -TUPLE: checkbox < string ; - -: ( id label -- component ) - checkbox swap new-component ; diff --git a/extra/http/server/components/farkup/farkup.factor b/extra/http/server/components/farkup/farkup.factor deleted file mode 100755 index 87b7170bbf..0000000000 --- a/extra/http/server/components/farkup/farkup.factor +++ /dev/null @@ -1,17 +0,0 @@ -! Copyright (C) 2008 Slava Pestov -! See http://factorcode.org/license.txt for BSD license. -USING: splitting kernel io sequences farkup accessors -http.server.components xml.entities ; -IN: http.server.components.farkup - -TUPLE: farkup-renderer < text-renderer ; - -: ( -- renderer ) - farkup-renderer new-text-renderer ; - -M: farkup-renderer render-view* - drop string-lines "\n" join convert-farkup write ; - -: ( id -- component ) - - >>renderer ; diff --git a/extra/http/server/components/inspector/inspector.factor b/extra/http/server/components/inspector/inspector.factor deleted file mode 100644 index 42366b57e4..0000000000 --- a/extra/http/server/components/inspector/inspector.factor +++ /dev/null @@ -1,17 +0,0 @@ -! Copyright (C) 2008 Slava Pestov -! See http://factorcode.org/license.txt for BSD license. -USING: splitting kernel io sequences inspector accessors -http.server.components xml.entities html ; -IN: http.server.components.inspector - -SINGLETON: inspector-renderer - -M: inspector-renderer render-view* - drop [ describe ] with-html-stream ; - -TUPLE: inspector < component ; - -M: inspector component-string drop ; - -: ( id -- component ) - inspector inspector-renderer new-component ; diff --git a/extra/http/server/components/test/form.fhtml b/extra/http/server/components/test/form.fhtml deleted file mode 100755 index d3f5a12faa..0000000000 --- a/extra/http/server/components/test/form.fhtml +++ /dev/null @@ -1 +0,0 @@ - diff --git a/extra/http/server/forms/forms.factor b/extra/http/server/forms/forms.factor deleted file mode 100644 index 92fb25bb16..0000000000 --- a/extra/http/server/forms/forms.factor +++ /dev/null @@ -1,79 +0,0 @@ -! Copyright (C) 2008 Slava Pestov -! See http://factorcode.org/license.txt for BSD license. -USING: kernel accessors assocs namespaces io.files sequences fry -http.server -http.server.actions -http.server.components -http.server.validators -http.server.templating ; -IN: http.server.forms - -TUPLE: form < component -view-template edit-template summary-template -components ; - -M: form init V{ } clone >>components ; - -: ( id -- form ) - form f new-component - dup >>renderer ; - -: add-field ( form component -- form ) - dup id>> pick components>> set-at ; - -: set-components ( form -- ) - components>> components set ; - -: with-form ( form quot -- ) - [ [ set-components ] [ call ] bi* ] with-scope ; inline - -: set-defaults ( form -- ) - [ - components get [ - swap values get [ - swap default>> or - ] change-at - ] assoc-each - ] with-form ; - -: ( form template -- response ) - [ components>> components set ] [ ] bi* ; - -: view-form ( form -- response ) - dup view-template>> ; - -: edit-form ( form -- response ) - dup edit-template>> ; - -: validate-param ( id component -- ) - [ [ params get at ] [ validate ] bi* ] - [ drop set-value ] 2bi ; - -: (validate-form) ( form -- error? ) - [ - validation-failed? off - components get [ validate-param ] assoc-each - validation-failed? get - ] with-form ; - -: validate-form ( form -- ) - (validate-form) [ validation-failed ] when ; - -: render-form ( value form template -- ) - [ - [ from-tuple ] - [ set-components ] - [ call-template ] - tri* - ] with-scope ; - -M: form component-string drop ; - -M: form render-summary* - dup summary-template>> render-form ; - -M: form render-view* - dup view-template>> render-form ; - -M: form render-edit* - nip dup edit-template>> render-form ; diff --git a/extra/http/server/validators/validators-tests.factor b/extra/http/server/validators/validators-tests.factor deleted file mode 100755 index 5e845705ab..0000000000 --- a/extra/http/server/validators/validators-tests.factor +++ /dev/null @@ -1,29 +0,0 @@ -IN: http.server.validators.tests -USING: kernel sequences tools.test http.server.validators -accessors ; - -[ "foo" v-number ] must-fail -[ 123 ] [ "123" v-number ] unit-test - -[ "slava@factorcode.org" ] [ - "slava@factorcode.org" v-email -] unit-test - -[ "slava+foo@factorcode.org" ] [ - "slava+foo@factorcode.org" v-email -] unit-test - -[ "slava@factorcode.o" v-email ] -[ "invalid e-mail" = ] must-fail-with - -[ "sla@@factorcode.o" v-email ] -[ "invalid e-mail" = ] must-fail-with - -[ "slava@factorcodeorg" v-email ] -[ "invalid e-mail" = ] must-fail-with - -[ "http://www.factorcode.org" ] -[ "http://www.factorcode.org" v-url ] unit-test - -[ "http:/www.factorcode.org" v-url ] -[ "invalid URL" = ] must-fail-with diff --git a/extra/http/server/validators/validators.factor b/extra/http/server/validators/validators.factor deleted file mode 100755 index 7415787c79..0000000000 --- a/extra/http/server/validators/validators.factor +++ /dev/null @@ -1,85 +0,0 @@ -! Copyright (C) 2006, 2008 Slava Pestov -! See http://factorcode.org/license.txt for BSD license. -USING: kernel continuations sequences math namespaces sets -math.parser assocs regexp fry unicode.categories sequences ; -IN: http.server.validators - -SYMBOL: validation-failed? - -TUPLE: validation-error value reason ; - -C: validation-error - -: with-validator ( value quot -- result ) - [ validation-failed? on ] recover ; inline - -: v-default ( str def -- str ) - over empty? spin ? ; - -: v-required ( str -- str ) - dup empty? [ "required" throw ] when ; - -: v-optional ( str quot -- str ) - over empty? [ 2drop f ] [ call ] if ; inline - -: v-min-length ( str n -- str ) - over length over < [ - [ "must be at least " % # " characters" % ] "" make - throw - ] [ - drop - ] if ; - -: v-max-length ( str n -- str ) - over length over > [ - [ "must be no more than " % # " characters" % ] "" make - throw - ] [ - drop - ] if ; - -: v-number ( str -- n ) - dup string>number [ ] [ "must be a number" throw ] ?if ; - -: v-integer ( n -- n ) - dup integer? [ "must be an integer" throw ] unless ; - -: v-min-value ( x n -- x ) - 2dup < [ - [ "must be at least " % # ] "" make throw - ] [ - drop - ] if ; - -: v-max-value ( x n -- x ) - 2dup > [ - [ "must be no more than " % # ] "" make throw - ] [ - drop - ] if ; - -: v-regexp ( str what regexp -- str ) - >r over r> matches? - [ drop ] [ "invalid " prepend throw ] if ; - -: v-email ( str -- str ) - #! From http://www.regular-expressions.info/email.html - "e-mail" - R' [A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}'i - v-regexp ; - -: v-url ( str -- str ) - "URL" - R' (ftp|http|https)://(\w+:?\w*@)?(\S+)(:[0-9]+)?(/|/([\w#!:.?+=&%@!\-/]))?' - v-regexp ; - -: v-captcha ( str -- str ) - dup empty? [ "must remain blank" throw ] unless ; - -: v-one-line ( str -- str ) - dup "\r\n" intersect empty? - [ "must be a single line" throw ] unless ; - -: v-one-word ( str -- str ) - dup [ alpha? ] all? - [ "must be a single word" throw ] unless ; From 376c73c7c86e69ec84ecab4fd212f342ef16b7d5 Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Fri, 23 May 2008 22:20:27 -0500 Subject: [PATCH 10/39] Convert HTML streams to use inheritance and new accessors, fix a bug --- extra/html/streams/streams-tests.factor | 4 +- extra/html/streams/streams.factor | 93 ++++++++++++------------- 2 files changed, 49 insertions(+), 48 deletions(-) diff --git a/extra/html/streams/streams-tests.factor b/extra/html/streams/streams-tests.factor index 2084c7db18..14f1621346 100644 --- a/extra/html/streams/streams-tests.factor +++ b/extra/html/streams/streams-tests.factor @@ -1,6 +1,6 @@ USING: html.streams html.streams.private io io.streams.string io.styles kernel -namespaces tools.test xml.writer sbufs sequences ; +namespaces tools.test xml.writer sbufs sequences inspector ; IN: html.streams.tests : make-html-string @@ -70,3 +70,5 @@ M: funky browser-link-href ] [ [ H{ } [ ] with-nesting nl ] make-html-string ] unit-test + +[ ] [ [ { 1 2 3 } describe ] with-html-stream ] unit-test diff --git a/extra/html/streams/streams.factor b/extra/html/streams/streams.factor index b35f383bdc..e3f45e4c25 100755 --- a/extra/html/streams/streams.factor +++ b/extra/html/streams/streams.factor @@ -1,50 +1,44 @@ -! Copyright (C) 2004, 2006 Slava Pestov. +! Copyright (C) 2004, 2008 Slava Pestov. ! See http://factorcode.org/license.txt for BSD license. USING: generic assocs help http io io.styles io.files continuations io.streams.string kernel math math.order math.parser namespaces quotations assocs sequences strings words html.elements -xml.entities sbufs continuations destructors ; +xml.entities sbufs continuations destructors accessors ; IN: html.streams GENERIC: browser-link-href ( presented -- href ) M: object browser-link-href drop f ; -TUPLE: html-stream last-div? ; +TUPLE: html-stream stream last-div ; -! A hack: stream-nl after with-nesting or tabular-output is -! ignored, so that HTML stream output looks like UI pane output -: test-last-div? ( stream -- ? ) - dup html-stream-last-div? - f rot set-html-stream-last-div? ; +! stream-nl after with-nesting or tabular-output is +! ignored, so that HTML stream output looks like +! UI pane output +: last-div? ( stream -- ? ) + [ f ] change-last-div drop ; : not-a-div ( stream -- stream ) - dup test-last-div? drop ; inline + f >>last-div ; inline : a-div ( stream -- straem ) - t over set-html-stream-last-div? ; inline + t >>last-div ; inline : ( stream -- stream ) - html-stream construct-delegate ; + f html-stream boa ; over set-delegate ; - -: ( style stream class -- stream ) - >r (html-sub-stream) r> construct-delegate ; inline +: new-html-sub-stream ( style stream class -- stream ) + new + 512 >>stream + swap >>parent + swap >>style ; inline : end-sub-stream ( substream -- string style stream ) - dup delegate >string - over html-sub-stream-style - rot html-sub-stream-stream ; - -: delegate-write ( string -- ) - output-stream get delegate stream-write ; + [ stream>> >string ] [ style>> ] [ parent>> ] tri ; : object-link-tag ( style quot -- ) presented pick at [ @@ -99,11 +93,11 @@ TUPLE: html-sub-stream style stream ; ] if ; inline : format-html-span ( string style stream -- ) - [ - [ [ drop delegate-write ] span-tag ] object-link-tag + stream>> [ + [ [ drop write ] span-tag ] object-link-tag ] with-output-stream* ; -TUPLE: html-span-stream ; +TUPLE: html-span-stream < html-sub-stream ; M: html-span-stream dispose end-sub-stream not-a-div format-html-span ; @@ -132,11 +126,11 @@ M: html-span-stream dispose ] if ; inline : format-html-div ( string style stream -- ) - [ - [ [ delegate-write ] div-tag ] object-link-tag + stream>> [ + [ [ write ] div-tag ] object-link-tag ] with-output-stream* ; -TUPLE: html-block-stream ; +TUPLE: html-block-stream < html-sub-stream ; M: html-block-stream dispose ( quot style stream -- ) end-sub-stream a-div format-html-div ; @@ -159,38 +153,43 @@ M: html-block-stream dispose ( quot style stream -- ) PRIVATE> ! Stream protocol -M: html-stream stream-write1 ( char stream -- ) +M: html-stream stream-flush + stream>> stream-flush ; + +M: html-stream stream-write1 >r 1string r> stream-write ; -M: html-stream stream-write ( str stream -- ) - not-a-div >r escape-string r> delegate stream-write ; +M: html-stream stream-write + not-a-div >r escape-string r> stream>> stream-write ; -M: html-stream make-span-stream ( style stream -- stream' ) - html-span-stream ; - -M: html-stream stream-format ( str style stream -- ) +M: html-stream stream-format >r html over at [ >r escape-string r> ] unless r> format-html-span ; -M: html-stream make-block-stream ( style stream -- stream' ) - html-block-stream ; +M: html-stream stream-nl + dup last-div? [ drop ] [ [
    ] with-output-stream* ] if ; -M: html-stream stream-write-table ( grid style stream -- ) - a-div [ +M: html-stream make-span-stream + html-span-stream new-html-sub-stream ; + +M: html-stream make-block-stream + html-block-stream new-html-sub-stream ; + +M: html-stream make-cell-stream + html-sub-stream new-html-sub-stream ; + +M: html-stream stream-write-table + a-div stream>> [ swap [ [ ] with each ] with each
    - >string write-html + stream>> >string write
    ] with-output-stream* ; -M: html-stream make-cell-stream ( style stream -- stream' ) - (html-sub-stream) ; - -M: html-stream stream-nl ( stream -- ) - dup test-last-div? [ drop ] [ [
    ] with-output-stream* ] if ; +M: html-stream dispose stream>> dispose ; : with-html-stream ( quot -- ) output-stream get swap with-output-stream* ; inline From 53857fdfee998019c90d8d8b1d126f2a0db17cc8 Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Fri, 23 May 2008 22:32:39 -0500 Subject: [PATCH 11/39] Move farkup, code, inspector components to html.components --- extra/html/components/components-tests.factor | 27 +++++++++++++++++-- extra/html/components/components.factor | 23 +++++++++++++++- 2 files changed, 47 insertions(+), 3 deletions(-) diff --git a/extra/html/components/components-tests.factor b/extra/html/components/components-tests.factor index 0bd5410a3b..d09f8b6b42 100644 --- a/extra/html/components/components-tests.factor +++ b/extra/html/components/components-tests.factor @@ -1,6 +1,7 @@ IN: html.components.tests -USING: html.components tools.test kernel io.streams.string -io.streams.null accessors ; +USING: tools.test kernel io.streams.string +io.streams.null accessors inspector html.streams +html.components ; [ ] [ blank-values ] unit-test @@ -145,3 +146,25 @@ M: link-test link-href drop "http://www.apple.com/foo&bar" ; [ "arbitrary markup for the win!" ] [ [ "html" html render ] with-string-writer ] unit-test + +[ ] [ "int x = 4;" "code" set-value ] unit-test + +[ ] [ "java" "mode" set-value ] unit-test + +[ "int x = 4;\n" ] [ + [ "code" "mode" >>mode render ] with-string-writer +] unit-test + +[ ] [ "-foo\n-bar" "farkup" set-value ] unit-test + +[ "
    • foo
    • bar
    " ] [ + [ "farkup" farkup render ] with-string-writer +] unit-test + +[ ] [ { 1 2 3 } "object" set-value ] unit-test + +[ t ] [ + [ "object" inspector render ] with-string-writer + [ "object" value [ describe ] with-html-stream ] with-string-writer + = +] unit-test diff --git a/extra/html/components/components.factor b/extra/html/components/components.factor index df1d1faa72..9c762eaa3a 100644 --- a/extra/html/components/components.factor +++ b/extra/html/components/components.factor @@ -4,7 +4,7 @@ USING: accessors kernel namespaces io math.parser assocs classes classes.tuple words arrays sequences splitting mirrors hashtables combinators continuations math strings fry locals calendar calendar.format xml.entities validators -html.elements ; +html.elements html.streams xmode.code2html farkup inspector ; IN: html.components SYMBOL: values @@ -144,6 +144,27 @@ M: link render* link-title object>string escape-string write ; +! XMode code component +TUPLE: code mode ; + +: ( -- code ) + code new ; + +M: code render* + [ string-lines ] [ drop ] [ mode>> value ] tri* htmlize-lines ; + +! Farkup component +SINGLETON: farkup + +M: farkup render* + 2drop string-lines "\n" join convert-farkup write ; + +! Inspector component +SINGLETON: inspector + +M: inspector render* + 2drop [ describe ] with-html-stream ; + ! HTML component SINGLETON: html From 6a1f38581692af69731eeefd7f4be570f0a94364 Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Fri, 23 May 2008 22:37:55 -0500 Subject: [PATCH 12/39] Add failing unit test --- extra/locals/locals-tests.factor | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/extra/locals/locals-tests.factor b/extra/locals/locals-tests.factor index c5adaa5e5e..87bc49f366 100755 --- a/extra/locals/locals-tests.factor +++ b/extra/locals/locals-tests.factor @@ -254,3 +254,14 @@ M:: fixnum next-method-test ( a -- b ) a call-next-method 1 + ; [ 3 ] [ 1 [let | a [ ] | 3 ] ] unit-test [ ] [ 1 2 [let | a [ ] b [ ] | ] ] unit-test + +:: a-word-with-locals ( a b -- ) ; + +: new-definition "IN: locals.tests\nUSING: math ;\n: a-word-with-locals ( -- x ) 2 3 + ;\n" ; + +[ ] [ new-definition eval ] unit-test + +[ t ] [ + [ \ a-word-with-locals see ] with-string-writer + new-definition = +] unit-test From 9100398adfb1343506a4762dc7ec993d3c4e4e75 Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Sat, 24 May 2008 01:28:48 -0500 Subject: [PATCH 13/39] Add more chloe tags, and tests --- extra/html/components/components.factor | 13 ++++--- extra/html/templates/chloe/chloe-tests.factor | 38 ++++++++++++++++++- extra/html/templates/chloe/chloe.factor | 16 +++++--- extra/html/templates/chloe/test/test8.xml | 27 +++++++++++++ 4 files changed, 83 insertions(+), 11 deletions(-) create mode 100644 extra/html/templates/chloe/test/test8.xml diff --git a/extra/html/components/components.factor b/extra/html/components/components.factor index 9c762eaa3a..faef9ca1b5 100644 --- a/extra/html/components/components.factor +++ b/extra/html/components/components.factor @@ -15,6 +15,9 @@ SYMBOL: values : blank-values H{ } clone values set ; +: prepare-value ( name object -- value name object ) + [ [ value ] keep ] dip ; inline + : from-tuple values set ; : values-tuple values get object>> ; @@ -35,7 +38,7 @@ GENERIC: render* ( value name render -- ) [ -rot render* ] dip render-error ] [ - [ [ value ] keep ] dip render* + prepare-value render* ] if* ;