View documentation | View discussion [638 posts] | View script | License |
Download script | History | Other scripts by: inetw3dm |
30-Apr 16:45 UTC
[0.132] 29.114k
[0.132] 29.114k
Archive version of: rebol-dom.r ... version: 27 ... inetw3dm 4-Mar-2021Amendment note: reformatted DOM functions. you can choose specific char to seperate key/values || Publicly available? Yes REBOL [ File: %rebol-dom.r Date: 02-11-2020 Title: "Dialect Object Model" Emai: inetw3.dm@gmail.com author: daniel murrill Purpose: { Use a recodable rebol function to create easy to follow blocks/series as a Dialect Object Model that allow different program languages to work together and viewed as HTML and VID. A parse alternative} ] library: [ author: daniel murrill level: 'intermediate platform: 'all type: Dialect domain: [html vid css json js array] tested-under: 'windows support: none license: none see-also: %HTML-view.r ] my-dialect: [body: [{background-color="blue" text "white"} ] p: [ { "color":"#0000ff", "bgcolor":"yellow", "width" : "399", "height" : "100" "font-styles": "big" } This is an example of an Dialect Oject Model b: [ {color = "Chocolate" bgcolor = "yellow"} that can be written to look like json' html' javascript arrays' css' i: [ {color = "green"} VID' or plain old rebol ] ] if you like. ] var anObj = { 100: 'a', 2: 'b', 7: 'c', }; hr: [{color="red" bgcolor="yellow"}] div: [ {width="399" bgcolor="orange"} b: [ {color: "purple" bgcolor: "orange"} Maybe it would be easier to write i: [ {color: "green"} MakeDoc.r code but the purpose of this rebol DOM is'] ] ] lua-tbl = {[first] = "fred", [last] = "cougar"} #this-issue [{color: "purple" bgcolor: "orange"}] p: [ {width "399" height= 200 style="color: red; bgcolor: brown; border: 2x2;" } b: [ {color="red"} to read or load as many well known dialects of coding styles as possible and write all of it as a single or seperate legible rebol series that's quickly manipulated' transcoded as html' and viewed as a VID. ] ] ] document.: func [request-as][ attempt [ DOM: head DOM if block! != type? data-node [this: copy data-node insert data-node: [] this] if data-node/1 [ data: type? data-node/1 either equal? data tag! [node-element: data-node/1 use*=*to-set-values var .style: = node-element style: :array-obj! .style: :array-obj! ] [node-element: data-node/1: build-tag to-block first parent-node: data-node] var .style: = node-element style: :array-obj! .style: :array-obj! ] return node-element ]use*=*to-set-values styles: "" ] return-tag-node: does [=: :equal? if block! != type? data-node [this: copy data-node insert data-node: [] this] if type? block! = node-element: data-node/1 [ replace/all node-element [=] [] node-element: data-node/1: build-tag to-block node-element ] ] .style: [] equal?: := DOM: DSL: html: window: end-tag: "" data-node: parent-node: node: none .body: .hr: .p: .b: .i: .tr: .ul: .li: .table: .td: .button: .input: .div: .font: .span: 0 node-obj: node-element: node-name: *name: use-methods: attr-name: attr-value: none check: func [select-this][node-name: select-this =: :equal? any [ if block! = type? select-this [ select-this: first parse/all node-name " "] if string! = type? select-this [select-this: first parse/all node-name " "] if tag! = type? select-this [select-this: first parse/all node-name " "] ] ] strip-chars-from: func [node-name][ foreach char elemt-chars: ["{" "}" {"} "(" ")" "/" "." "[" "]" "," ":" ";" "," "=" ][ replace/all node-name char " " ] ] strip-obj-chars-from: func [node-name][ trim node-name if #"^"" = node-name/1 [remove node-name] foreach [-char +char] obj-chars: [#"^/" " " "," "" {" : "} {: "} {":"} {: "} {":} {:} {" "} {" } { " } "" "[" "" "]" "" {""} {"} { "} "" ":" "" { =} {=} {=} " " "'" "" ][ replace/all node-name -char +char ] ] getnodename: func [node-name][count: [] DOM: head DOM =: :equal? either block! = type? node-name [data-node: :node-name if error? try [ node-element: data-node/1: build-tag data-node/1][ node-element: data-node] ][ node-name: to block! strip-chars-from form node-name if error? try [count: pick find node-name integer! 1][count: 1] if error? try [nodename: to-word join "." array-obj!: node-name/1 repeat ? count [data-node: first DOM: next node: find DOM nodename] ][print reduce ["node-name:" mold form node-name/1 "not found"] ] return either tag! = type? data-node/1 [node-element: data-node/1][node-element: data-node] slf: join node-name/1 count ] ] setnodename: func [old-name new-name][ this-name: check strip-chars-from old-name node-element-name: check node-element if this-name != node-element-name [getnodename old-name] if not find node-element new-name [ replace node-element to string! this-name new-name replace data-node to-tag join "/" this-name to-tag join "/" new-name ] ] getattribute: func [attr-name][ attr-value: none either attempt [do compose/deep [attr-value: array-obj![(attr-name)]] ][print reduce [attr-name attr-value] ][print reduce ["node-attribute:" mold form attr-name "not found"] ] ] setattribute: func [attr-name new-attr][ return-tag-node *value: none any [ if *value [replace node-element attr-name new-attr do compose/deep [array-obj![(form attr-name)]] ;get-attributes node-element attempt [set-attributes] ] attempt [insert tail node-element " " do compose/deep [array-obj![join (new-attr) {="undefined"}]]] print reduce ["Must get a parent-node with this attribute: " attr-name]] ] setattributevalue: func [attr-name attr-value][ key: form reduce attr-name any [ if find node-element key [ do compose/deep [.style[(key)] `= (attr-value)] ;get-attributes node-element attempt [set-attributes] ] attempt [join node-element to string! reduce [" " attr-name {="} attr-value {"}] ;get-attributes node-element attempt [set-attributes] ] print reduce ["Must get a parent-node with this attribute: " attr-name] ] ] getElementByTagName: func [array-obj! selection [block!]][ dom: head dom repeat this first selection [ node-element: first data-node: first dom: next find dom to-word join "." array-obj! ] if [use-methods and not find node-element " ." ][use-attr-as-methods yes] use-methods: off ] use*=*to-set-values: does [=: func [value][any [value]]] use-attr-as-methods: func [maybe [logic!]][ if maybe [foreach [-char +char][{" } {" .}][replace/all node-element -char +char] ] replace node-element " " " ." use-methods: yes ] node-list: [] var: func [var-data][node-element: "" if error? try [ variable: first parse var-data "=:, " node-element: copy var-data ][ either not empty? node-element [ variable: first parse node-element "=:, " ][ variable: to-string reduce var-data node-element: "" ] ] use*=*to-set-values if empty? node-element [if not find node-list variable [append node-list reduce [form variable node-element: any [attempt [do :variable] :variable] " "]]] if not find node-list variable [append node-list reduce [variable node-element]] do reform ["array-obj!: " join variable ":" {func [key [block! word! string!]][if not equal? tag! type? node-element [node-element: select node-list } mold variable {] any [ if empty? form key [return trim any [ attempt [remove/part find node-element ": =" 3] attempt [remove/part find node-element ": " 2] node-element ] ] attempt [*value: first next find parse form parse/all node-element {=:} {;,} *key: form key] attempt [do head insert next key [node-element join]] if not find node-element key []] ; can be [print [*key "not found"]]] ]} ] attempt [if not find variable "." [do load to-string reduce ["set " #"'" variable ". :array-obj!"]]] attempt [set to-word var-data copy :array-obj!] use-methods: off ] arr=: `=: func[value][ equal: '= either equal? *value/1 #"'" [ replace node-element *value to-string reduce ["'" value "'"] ] [ either find node-element mold form *value [ replace node-element mold *value mold value ][ replace node-element *value value ] replace/all node-element {""} {"} ] ] node-element: array-obj!: key: *key: *value: "" markup-DOM: func [DSL][DOM: DSL either block! = type? DSL [ either find DSL <rebol-DOM type="text/html"> [] [insert DSL <rebol-DOM type="text/html"> DOM: DSL: load replace/all mold DSL "__" " " get-data: func [data][ find-end-tag: find data get-word! either find-end-tag [ replace data first find-end-tag to-tag mold to-refinement first find-end-tag][insert tail data to-tag join "/" any [*name *node-name] ] repeat in-data data [cnt: 0 if set-word! = type? in-data [*node-name: copy form in-data replace data in-data node-name: to-word join "." *node-name ] if string! = type? in-data [ strip-obj-chars-from in-data insert in-data next reform [node-name " "] child: build-tag to-block in-data ;foreach [a b][" " " ."][replace/all child a b] replace data in-data child ] if block! = type? in-data [ set to-word join *node-name cnt: cnt + 1 in-data get-next in-data ] ] ] get-next: func [in-data][ repeat data in-data [ if set-word! = type? data [*name: copy form data replace in-data data node-name: to-word join "." *name ] if string! = type? data [ strip-obj-chars-from data insert data next reform [node-name " "] child: build-tag to-block data ;foreach [a b][" " " ."][replace/all child a b] replace in-data data child ] if block! = type? data [get-data data set to-word *node-name data] ] find-end-tag: find in-data get-word! either find-end-tag[ replace in-data first find-end-tag to-tag mold to-refinement first find-end-tag][insert tail in-data to-tag join "/" any [*node-name *name] clear *node-name] ] repeat with-this-data DSL [ if issue! = type? with-this-data [ node-name: to-word join "." *name: copy form with-this-data ] if set-word! = type? with-this-data [ replace DSL with-this-data node-name: to-word join "." *name: copy form with-this-data ] if word! = type? with-this-data [ either '= = with-this-data [string-is-data: yes replace DSL with-this-data "" ][ *name: copy form with-this-data replace DSL with-this-data node-name: to-word join "." with-this-data] replace DSL reduce [node-name node-name] node-name ] if string! = type? with-this-data [ either string-is-data [replace DSL with-this-data join node-name with-this-data][ created-data: copy with-this-data strip-obj-chars-from created-data insert created-data reduce [node-name " "] child: build-tag to-block remove created-data ;foreach [a b][" " " ."][replace/all child a b] replace DSL with-this-data child ] string-is-data: no ] if block! = type? with-this-data [ get-data with-this-data ] if get-word! = type? with-this-data [ replace DSL with-this-data to-tag mold to-refinement *name ] ] ] ][ alert "Need a Dialect Object Model as type! block" ] replace/all dsl "" [] DOM: copy DSL ] return-html-dsl: does [ html: copy form any [find head DOM "<body" head DOM] replace/all replace/all html "<." "<" "' " ", " replace/all replace/all html "{" "<" "}" ">" foreach n-name [ ".body " ".hr " ".p " ".b " ".i " ".? " ".tr " ".table " ".td " ".button " ".input " ".div " ".ul " ".li " ".font " ".span " ".img " ".a " ".strong " " ." ".hr " "lua-tbl " ][replace/all html n-name " " ] append replace/all html </body> "" </body> html: any [find html "<body" html] ] { ************************************************************************************************** An example of how to use the DOM functions follows. The syntax hopefully should be easy to follow being that it resembles how you would use javascript with the HTML,XML DOM. It's just a little bit different, why not just make it the same? Were not scripting against a DOM, (a Documents Object Modle) but a DOM, (a Dialect Object Modle) because you may not actually know the syntax of the loaded document or data before it's transcode to a DOM from a DSL. Plus Rebol wont let you too far off the hook in writing code any way you like. Some *op Words and code/data has set types that follow a strict syntax. I think the best way around this is to load as type? string!, reformat and parse as type? block!. Maybe..... These DOM functions should work very close to the HTML DOM functions: getElementsByTagName .getAttribute .setAttribute } markup-DOM my-dialect document. getnodename {"div"[1]}getattribute "bgcolor" document. getnodename{("p")[2]} .style[width] `= "block-build" setattributevalue('height) "1000" node-element getattribute "height" setnodename {hr[1]} "listview" node-element document. getnodename{("p")[1]}.style[font-styles] `= "block-build" setattribute('font-styles)"whithouse" setattributevalue('boogies)"green-color" data-node: do to-path [DOM .p .b] document.(data-node).style[color] `= "bluberry" setattribute('i-style) "silly" ; some examples of selecting keys and values set to variables as an array object. ; good to use with anything that's structured with {} or " ". ;IE (javascript, json objects/arrays.. lua table/arrays.. associative arrays etc.) ;even DOM's and rebol data. ;you must use use*=*to-set-values before setting the first variable. ;it will use = to set any value to a variable (a set-word) ;`= this literal equal is used to set values to keys use*=*to-set-values ;variables and there values (node-elements) are sent and fetched from a ;node-list block for demo purposes. They will be appended to the DOM later. ;The variable name and the first word in it's value must be the same in order for ;the value to be set as a node-element thats bound to the array-obj! function. var anObj: = {anObj 100:"a" 2 : "two words" 7="c"} anObj[2] anObj[2] `= "a to z" node-element use-methods: yes var app: = document.(getElementByTagName('p)[2]) ;call/associate the array-obj! with this variable name ;because the variable name "app" and the node-name "p" ;are not the same. app: :array-obj! ;the style.obj! is auto created by using the document. function .style["bgcolor"] ;is the same as calling app[bgcolor] app[.width] `= "curly quew" app ('bgcolor) `= {'purple'} ;when you need to create a variable to use with an array-obj! var join {poppy } {100:"a" street : "backside" 7="c"} ;you don't need a set-word! variable. It will always be the first ;word followed by ": =", ": ", or " " found in the value (node-element). ;you can access it with array-obj![]. But the value will change once ;a new VAR is created and you'll you to select it from the node-list. poppy[street]`="old rover rd." poppy[7] `= "cities" ;DOM variables are renamed to start with a dot "." so not to be confused with words. ;this will change in the future. All DOM Var's will be type! set-word!. ;Remember when calling a node-name and using that name as the variable, var .anObj: = getnodename "anobj" ;you dont have to call/associate the array-obj! with this variable name ;but the variable name must began with a dot. IE "." .anobj[7] ;but with var anObj: = getnodename "anobj" ;you do anObj: :array-obj! anobj[7] ;after calling some variable[key]/array-obj![key], you can replace the key and value. replace replace node-element *key 'this-key *value {'some-value'} data-node var 'try-this try-this.[insert (add 50 50) ", "] node-element try-this.[append ", "("new-value")] try-this[toot] ;a roadmap for javascripting with the Dialect Object Model (DOM). ;This code... { function welcomeSite() { siteMessage = "Welcome to the..."; console.log(siteMessage); var siteMessage; } welcomeSite(); siteMessage.append("Rebolution") siteMessage } ;Is changed to this code... do js-op!: [*: :do console.log: :print var 'use js-do: :*] welcomeSite: does [*{ siteMessage: = "Welcome to the... " Message-type: "Welcome" console.log(siteMessage); var 'siteMessage; }]; ;Hey you can load welcomeSite from a DOM or files with variables, functions, key-values or Rebol code: use[welcomeSite()]; ;to use the welcomeSite Message-type in your code. js-do { var say-hi-to: = Message-type console.log(["This is a message to" say-hi-to "you."]); } siteMessage.[append("Rebolution.")#"^/"] siteMessage.[print] var first-obj: = {first-obj: first-name: "Brigsby" last-name: "Backfort"} var second-obj: = {second-obj: first-name: "Krystal" last-name: "Frontbunker"} first-obj[last-name]`="FortBack" first-obj[] second-obj[last-name]`="Bunkerfront" second-obj[] Notes
|