Navigateur web intégré et piloté dans une application R2 View ou R3 GUI ? | |
deglingo | 24-Dec-2010/18:08:56+1:00 |
A votre avis, serait-il possible d'embarquer un navigateur web dans une application R2 View ou plus tard R3 GUI ? (en quelque sorte l'inverse du plugin IE/Firefox pour Rebol) + Eclipse RCP le fait par exemple avec son composant SWT Browser : (http://wiki.eclipse.org/index.php/RCP_Browser_Example ) + Eclipse RCP n'a pas redéveloppé un browser, il pilote le moteur d'1 des navigateurs installés sur le poste : IE piloté par OLE sur Windows, Mozilla (je crois) sur Linux, etc... + Il est capable de détecter des évènements venant du moteur du navigateur. Exemple : il détecte les changements de page grâce à un "LocationListener". Pensez-vous que cela soit possible avec Rebol, et notamment le dernier point (récupérer des évènements du navigateur) ? Est-ce que la librairie COMLib pourrait gérer cela, ou les extensions en R3 (avec le mécanisme de callbacks) ? Merci si vous avez des infos là-dessus. Et, joyeux noël à tous. | |
shadwolf | 26-Dec-2010/9:04:20+1:00 |
un navigateur web dans R3/GUI j'ai évoqué le sujet on m'a dit d'aller me faire foutre ca te semble assez clair? sur un plan complètement pratique il y a 2 façon de faire avec R3: 1) soit en passant par une librairie qui gère déjà le HTML comme webkit ou cairo suivant le niveau d'intégration qu'on veut. Evidement il faut aussi définir quel sera le niveau d'inter action voulu. Est ce qu'on veut du coté rebol une boite 2) soit en créant un moteur de rendu graphique en utilisant Draw/AGG. Comme le HTML a une vocation purement read only ca ne devrait pas être bien compliqué. Personnellement je sais comment faire ce genre de widget modifier mais je n'ai pas envi de passer mon temps libre sur le sujet pour que d'autre aillent vendre dans mon dos mes idées. | |
shadwolf | 26-Dec-2010/9:09:59+1:00 |
Enfin notre guru a tous Carl prefererait que MakeDoc soit ulisé plutot que HTML, pour ce qui est de la documentation. c'est pourquoi on entend parler depuis quelques années d'une widget de rendu MakeDoc. | |
deglingo | 27-Dec-2010/13:20:57+1:00 |
Merci pour la réponse. En fait, mon objectif serait de ne pas redévelopper la roue, en l'occurence un navigateur web, de l'encapsuler dans une application graphique Rebol, et du coup de bénéficier de toutes ses capacités (javascript, html, et autres), sans avoir à developper un moteur de rendu graphique HTML, un interpréteur Javascript, sans avoir non plus à passer par une librairie gérant le HTML . La librairie Java SWT permet de faire cela parce qu'elle attaque directement les composants bas niveau installés sur le système d'exploitation sur lequel elle tourne (les fenêtres ont directement le look & feel du système). C'est pour cela qu'elle peut afficher le rendu graphique d'un navigateur web existant (IE, Firefox, etc...) et de ses plugins à l'intérieur d'une fenêtre SWT. | |
Didec | 27-Dec-2010/15:02:20+1:00 |
Maxim a réussi à encapsuler OpenGL alors je pense que via le host kit cela doit être possible. Mais là, j'y connais rien. Jocko à déjà fait pas mal de choses sympa, il a peut-être un avis sur la question ? | |
nve | 27-Dec-2010/18:05:11+1:00 |
Sous Windows, avec Delphi on pouvait à l'époque récupérer le composant IE et interagir avec directement depuis Delphi. shadwolf: je trouves cela dommage car un composant HTML permet énormément de choses. Il y a 2 type d'application : soit effectivement le moteur de rendu HTML pour VID... Mais surtout la partie exécution en silence pour faire du Mash-up. Parce qu'avec REBOL en tant que moteur de mash-up, cela aurait été vraiment terrible... | |
jocko | 1-Jan-2011/11:14:21+1:00 |
Sous R3, je pense que celà ne pose pas trop de problèmes d'intégrer un composant webbrowser dans une fenêtre rebol, via une extension. Il doit falloir pour celà récupérer le handle de la fenêtre rebol dans lequel on veut afficher ce composant. Ceci dit, je ne vois pas un gros intérêt à cette fonction, compte tenu que le navigateur est une application de base sur tous les systèmes. | |
shadwolf | 1-Jan-2011/11:24:33+1:00 |
nve dessiné du texte ave l'agg de rebol 2 c'est une vraie galère. des viewer makedoc et makedoc pro ont été réalisé il y a quelques années en se servant d'une technique rudimentaire de clonage et de composition de face sur le wiki j'avais écris un article sur le sujet il me semble. Tu peux partir de là et essayer de faire ton navigateur... L'ennorme problème c'est que le web c'est plus uniquement du HTML il y a aussi des technologies annexes comme les CSS, Flash, la video l'audio le javascript etc... Et là ca complique les choses. | |
shadwolf | 1-Jan-2011/11:25:09+1:00 |
nve dessiné du texte ave l'agg de rebol 2 c'est une vraie galère. des viewer makedoc et makedoc pro ont été réalisé il y a quelques années en se servant d'une technique rudimentaire de clonage et de composition de face sur le wiki j'avais écris un article sur le sujet il me semble. Tu peux partir de là et essayer de faire ton navigateur... L'ennorme problème c'est que le web c'est plus uniquement du HTML il y a aussi des technologies annexes comme les CSS, Flash, la video l'audio le javascript etc... Et là ca complique les choses. | |
nve | 1-Jan-2011/17:45:36+1:00 |
En fait, un composant viewer HTML n'a pas d'intérêt selon moi. Par contre, un composant HTML permettant de simuler l'exécution pourrait être très intéressant pour faire du mash-up et le coupler avec Cheyenne par exemple. Effectivement, il y a le pb du Flash, mais comptons sur 2 petites startup de la Sillicon Valley pour booster HTML 5. Restera la partie Javascript. La solution passe-t-elle par un appel de module externe navigateur Web ? Comme on faisait en quelque sorte en Delphi pour le viewer HTML IE intégré dans l'application... | |
ldci | 2-Jan-2011/15:33:10+1:00 |
Bonjour En recherchant dans mes archives, j'ai retrouvé sonar1.r qui avait été écrit en 2003 par errru@arcor.de Ca fonctionne à minima et peut servir de base à quelque chose de plus élaboré Amicalement #! /usr/bin/rebol REBOL [ Title: "SONAR1 web browser" Date: 3-Nov-2003 Version: 0.0.5 File: %sonar1.r Author: "errru" Rights: "GNU GPL" Email: errru@arcor.de Needs: [view 1.2.8] Purpose: {A small graphical web browser.} Note: { SONAR1 is a light-weight experimental web browser. Web pages are presented in a simplified layout, happily ignoring most of the HTML these pages usually consist of. For now, that is. Because this project worked out so well, there might actually come a more accurately rendering future version, SONAR2. Which will take some time. Tip: Besides URLs, you can also enter any valid REBOL expression in the address field, e.g: - alert "hi, there" ; display an alert box - alert form system/stats ; display allocated memory - alert reform links ; display all links - recycle ; recycle memory - read %file ; read address line from a file - save %file cache ; save cache to a file - clear cache ; clear the cache (see below) - repend cache load %file ; load the cache again - foreach l links [ .. ] ; ...you get the idea! Special words accepted in expressions: 'links points to a block of all links on page 'cache points to the in-memory cache 'history points to the history 'content points to the layout of the current page 'about views this text Still incomplete in this version of SONAR1: - improve asynchronous downloading - further testing and debugging - display text files in <pre> ... </pre> format - HTML forms - cookies <a href="mailto:errru@arcor.de"> Drop me an email</a>if you have questions or suggestions! } History: [ 0.0.1 [31-Aug-2003 "first version of SONAR1"] 0.0.3 [03-Sep-2003 "a myriad of things"] 0.0.4 [18-Sep-2003 "detecting redirects, restructured html/process"] 0.0.5 [3-Nov-2003 "alive? always set to true" "goto uses correct suffix" "over feel for links"] ] ] if system/version < second system/script/header/needs [ alert reform ["This script needs" system/script/header/needs "to run"] quit ] SONAR1: context [ options: context [ default-address: "about" favorites: copy [http://www.rebol.com] images: true image-minsize: 23x23 indent: 20 margin: 80x12 min-width: 300 max-width: 800 cache-limit: 200 user-agent: copy system/schemes/HTTP/user-agent view-size: 600x340 window-offset: 20x20 ] current-address: http:// content: none history: make block! 100 cache: make block! 100 STOP: false window: none options-window: none f-view: none f-address: none f-scroller: none f-go: none f-fav: none f-add: none f-status: none f-textwidth: none f-choose-fav: none whitespace: charset " ^-^/" alpha-num: charset [#"a" - #"z" #"A" - #"Z" #"0" - #"9"] keymap: [ #"^M" [if same? system/view/focal-face f-address [evaluate-address]] up [scroll-by -1] down [scroll-by 1] page-up [scroll-by/page -1] page-down [scroll-by/page 1] f1 [skip-history -1] f2 [skip-history 1] f3 [STOP: true] f4 [edit-options] ] signatures: [ image! [ #{474946383761} ;; GIF87a #{474946383961} ;; GIF89a #{FFD8FF} ;; JFIF #{89504E470D0A1A0A} ;; PNG #{4D42} ;; Microsoft DIB ] ] extensions: [ image! [ ;; used to guess if it's an image %.gif %.jpeg %.jpg %.png %.bmp ] ] char-entities: [ "amp" #"&" "quot" #"^"" "lt" #"<" "gt" #">" "nbsp" #" " ] ;; assuming ISO 8859-1 (latin 1) charset on client computer use [c] [ c: #"^(A1)" foreach n [ "iexcl" "cent" "pound" "curren" "yen" "brvbar" "sect" "uml" "copy" "ordf" "laquo" "not" "shy" "reg" "macr" "deg" "plusmn" "sup2" "sup3" "acute" "micro" "para" "middot" "cedil" "sup1" "ordm" "raquo" "frac14" "frac12" "frac34" "iquest" "Agrave" "Aacute" "Acirc" "Atilde" "Auml" "Aring" "AElig" "Ccedil" "Egrave" "Eacute" "Ecirc" "Euml" "Igrave" "Iacute" "Icirc" "Iuml" "ETH" "Ntilde" "Ograve" "Oacute" "Ocirc" "Otilde" "Ouml" "times" "Oslash" "Ugrave" "Uacute" "Ucirc" "Uuml" "Yacute" "THORN" "szlig" "agrave" "aacute" "acirc" "atilde" "auml" "aring" "aelig" "ccedil" "egrave" "eacute" "ecirc" "euml" "igrave" "iacute" "icirc" "iuml" "eth" "ntilde" "ograve" "oacute" "ocirc" "otilde" "ouml" "divide" "oslash" "ugrave" "uacute" "ucirc" "uuml" "yacute" "thorn" "yuml" ][ repend char-entities [n c] c: c + 1 ] ] ;; see http://home.arcor.de/roland.hadinger/rebol/includes/2.demos/guard.r guard: func [ {Evaluates a block only at the first recursion level, otherwise ignores it.} [catch] block [block! none!] "block to guard" /status 'blocked? [word!] "get blocked status" /local guard-blocks result ][ guard-blocks: [#[none]] if status [set blocked? true] if foreach b guard-blocks [ if same? block b [break/return none] true ][ if status [set blocked? false] insert/only guard-blocks block set/any 'result do block remove guard-blocks get/any 'result ] ] init: does [ set-options/reload window: layout window-layout layout-size: window/size view-page "" 0x0 ;; creates empty pane center-face window ;view/new/options/offset window [resize] options/window-offset view/new/options window [resize] window/feel: make window/feel [ detect: func [face event] [ switch event/type [ scroll-line [scroll-by event/offset/y] scroll-page [scroll-by/page event/offset/y] resize [resize-window return true] key [switch event/key keymap] offset [options/window-offset: event/offset] ] event ] ] alive?: true do-events ] link-feel: make svv/vid-styles/BUTTON/feel [ engage: func [face action event] [ switch action [ time [ if not face/state [face/blinker: not face/blinker] ] down [ face/state: on show-address face/user-data/2 ] alt-down [ face/state: on show-address face/user-data/2 ] up [ show-address none if face/state [want face/user-data/2] face/state: off ] alt-up [ show-address none if face/state [save-resource face/user-data/1] face/state: off ] over [ face/state: on ] away [ face/state: off ] ] cue face action show face ] over: func [face action event] [ if all [face/font face/font/colors] [ either action [ face/font/color: pick face/font/colors 2 show-address face/user-data/2 ][ face/font/color: pick face/font/colors 1 show-address none ] show face face/font/color: first face/font/colors ] ] ] window-styles: stylize [ btn-bright: btn 50x24 bold 255.172.0 btn-normal: btn 100x24 bold 255.255.255 status: text 0.0.0 229.227.218 no-wrap fld-adr: field 100x23 101.98.95 101.98.95 font [ color: 255.255.255 ] bold edge [ size: 0x0 ] para [ origin: 6x2 ] ] view-styles: stylize [ hypertext: text para [origin: 2x4 margin: 2x6] font [space: 0x4 style: none] boldtext: text para [origin: 2x4 margin: 2x6] font [space: 0x4 style: 'bold] pretext: code no-wrap as-is para [origin: 2x2 margin: 2x4] font [space: 0x4 style: none] hyperlink: button 248.248.248 edge [size: 1x1 color: 224.224.224] font [colors: [0.0.0 255.224.0] shadow: none style: none] effect [] with [feel: link-feel] hyperlink-image: button 255.255.255 edge [size: 2x2 color: 0.0.0] font [colors: [0.0.0 255.224.0] shadow: none] effect [] with [feel: link-feel] static-image: button 255.255.255 edge [size: 0x0 color: 0.0.0] font [colors: [0.0.0 255.224.0] shadow: none] effect [] with [feel: link-feel] hrule: box 100x1 0.0.0 bullet: box 8x8 0.0.0 effect [oval 255.255.255] ] layout [ f-choose-fav: choice 150x20 75.73.71 156.151.147 left font [colors: [255.255.255 255.255.255] size: 11 shadow: 0x0 style: 'bold] edge [size: 0x0 color: 0.0.0] para [origin: 10x2] ] layout [ styles view-styles f-textwidth: hyperlink 1000 "" ] ;; main window window-layout: [ styles window-styles backcolor 0.0.0 origin 0 space 8x8 across pad 8x8 btn-normal "< back" [skip-history -1] btn-normal "next >" [skip-history 1] btn-normal "stop" [STOP: true] btn-normal "options" [edit-options] return pad 8x2 f-address: fld-adr (copy options/default-address) (options/view-size * 1x0 + -178x22) pad 4x-2 f-go: btn-bright "go" [evaluate-address] f-fav: btn-bright "fav" [choose-favorite] f-add: btn-bright "+/-" [alter-favorite] return space 0 f-view: box options/view-size 255.255.255 f-scroller: slider options/view-size * 0x1 + 20x0 0.0.0 255.255.255 edge [ size: 1x1 ][ scroll-view ] return f-status: status options/view-size * 1x0 + 20x18 "" sensor 0x0 rate 5 [guard [wait 0]] ] layout-size: 0x0 resize-window: has [ delta ][ window/size: max window/size 540x200 delta: window/size - layout-size layout-size: window/size f-address/size/x: f-address/size/x + delta/x f-go/offset/x: f-go/offset/x + delta/x f-fav/offset/x: f-fav/offset/x + delta/x f-add/offset/x: f-add/offset/x + delta/x f-view/size: f-view/size + delta f-scroller/size/y: f-scroller/size/y + delta/y f-scroller/offset/x: f-scroller/offset/x + delta/x f-status/offset/y: f-status/offset/y + delta/y f-status/size/x: f-status/size/x + delta/x options/view-size: f-view/size show window scroll-by 0 ] ;; opens options-window edit-options: has [f1 f2 f3 f4 f5 f6 f7 f8 f9] [ if all [options-window viewed? options-window] [return] options-window: layout [ style text2 text 150 right 255.255.255 bold style field2 field 200 edge [size: 1x1 color: 0.0.0] style button2 btn 60 0.0.0 font [colors: [255.255.255 255.255.255]] bold style check2 check edge [size: 2x2 color: 0.0.0] backcolor 101.98.95 space 4x4 across text2 "default address" f1: field2 (copy options/default-address) return text2 "show images" f2: check2 (options/images) return text2 "minimum image size" f3: field2 (mold options/image-minsize) return text2 "indent width" f4: field2 (mold options/indent) return text2 "margin" f5: field2 (mold options/margin) return text2 "minimum width" f6: field2 (mold options/min-width) return text2 "maximum width" f7: field2 (mold options/max-width) return text2 "cache limit" f8: field2 (mold options/cache-limit) return text2 "user agent string" f9: field2 (copy options/user-agent) return pad 230x20 button2 "OK" [ options/default-address: copy f1/text options/images: f2/data options/image-minsize: any [attempt [to-pair f3/text] options/image-minsize] options/indent: any [attempt [to-pair f4/text] options/indent] options/margin: any [attempt [to-pair f5/text] options/margin] options/min-width: any [attempt [to-integer f6/text] options/min-width] options/max-width: any [attempt [to-integer f7/text] options/max-width] options/cache-limit: any [attempt [to-integer f8/text] options/cache-limit] options/user-agent: copy f9/text save-options set-options unview ] button2 "cancel" [unview] ] view/new center-face/with options-window window ] set-options: func [/reload] [ if reload [ attempt [ options: make options bind to-block read %sonar1-options.r 'system ] ] if not empty? options/user-agent [ system/schemes/HTTP/user-agent: copy options/user-agent ] ] save-options: does [ attempt [ save %sonar1-options.r third options ] ] scroll-view: does [ if all [f-view content] [ content/offset/y: to-integer f-scroller/data * content/size/y * -1 ] guard [ wait 0 show f-view ] ] scroll-by: func [n /page] [ f-scroller/data: min max 0.0 f-scroller/data + ( n * (either page [f-view/size/y] [20]) / max 1 content/size/y ) 1.0 show f-scroller scroll-view ] decode-entities: func [ text [string!] /local result e c n ][ result: copy "" parse/all text [ any [ end break | #"&" opt [ "#x" copy e to #";" skip ( c: attempt [ all [ n: debase/base e 16 1 = length? n to-char first n ] ] ) | #"#" copy e to #";" skip ( c: attempt [ all [ n: to-integer e 1 <= n 255 >= n to-char n ] ] ) | copy e to #";" skip ( c: select/case char-entities e ) ] ( if c [append result c c: none] ) | copy e [to #"&" | to end] ( if e [append result e] ) ] ] result ] evaluate-address: has [result] [ either error? set/any 'result try [ do bind load/all f-address/text in context [ history: SONAR1/history cache: head SONAR1/cache links: head SONAR1/html/links content: head SONAR1/html/content about: get in SONAR1 'view-about-info ] 'self ][ result: disarm result alert reform bind (get result/id) (in result 'id) ][ if all [ not unset? get/any 'result any [ file? result url? result email? result none? result ] ][ want result ] ] ] choose-favorite: has [list f] [ list: copy [] f-choose-fav/size/x: f-address/size/x + 178 foreach f options/favorites [ append list either string? f [f] [mold/only f] ] choose/style/window/offset list func [face btn] [ f-address/text: copy face/text f-address/line-list: none ] f-choose-fav window f-address/offset + (f-address/size * 0x1) ] alter-favorite: has [value f] [ if all [ value: attempt [load f-address/text] value <> 'none not all [series? value empty? value] ][ either found? f: find/only options/favorites value [ if confirm reform ["Really remove" mold f/1 "from favorites?"] [ remove f ] ][ append/only options/favorites value ] ] ] want: func [ address [file! url! email! none!] /local new ][ either email! = type? address [ emailer/to address ][ if new: absolute-address address [ if all [not empty? head history f-view/pane] [ change back history f-view/pane/1/offset ] history: tail repend clear history [copy new 0x0] ] goto new 0x0 ] ] goto: func [ address [file! url! none!] offset [pair!] /local resource suffix ][ guard [ suffix: suffix? any [address ""] resource: get-resource address any [ all [ find extensions/image! suffix image! ] string! ] f-address/text: mold current-address: first resource f-address/line-list: none view-page second resource offset f-status/text: either any [ none? first resource not none? second resource ][ "" ][ reform [address "not found"] ] show window ] ] view-about-info: does [ view-page rejoin ["<h1>About SONAR1</h1><hr><pre>" system/script/header/note "</pre>"] 0x0 show window ] show-address: func [ address ][ f-status/text: form any [address ""] show f-status ] view-page: func [ data [string! image! none!] offset [pair!] ][ content: copy [ styles view-styles backcolor 255.255.255 space 2x2 origin (options/margin) ] append content any [ switch type? data reduce [ string! [ html/process data min options/max-width options/view-size/x - 20 ] image! [ compose [image (data)] ] ] copy [] ] f-view/pane: reduce [content: layout content] f-status/text: none f-status/line-list: none f-view/pane/1/offset: offset f-scroller/data: f-view/pane/1/offset/y / f-view/pane/1/size/y * -1 ] save-resource: func [ address [any-string!] /local file data ][ if any [file? address url? address] [ if file: request-file/file/save/only second split-path address [ if data: second get-resource address binary! [ write/binary file data f-status/text: join form file " saved." show f-status ] ] ] ] skip-history: func [value /local new offset] [ history: skip history value * 2 goto history/-2 any [history/-1 0x0] false ] strip-address: func [address [any-string!]] [ copy/part address any [find address #"#" tail address] ] absolute-address: func [ address [any-string! none!] /local new dec host p ][ if any [none? address empty? address] [return none] if file? address [return clean-path address] if email? address [return address] new: copy http:// if p: find/match address new [ address: either (index? find/last address #"/") > (index? find back p #"/") [ copy address ][ join address #"/" ] return attempt [to-url address] ] if file? current-address [ return none ] dec: decode-url current-address if not dec/host [ return none ] repend new [dec/host #"/"] host: copy new if all [dec/path #"/" <> address/1] [ repend new [dec/path] ] until [ not any [ if all [ find/match address "../" p: find/last/any new "/?" (index? p) > length? host ][ remove/part address 3 new: copy/part new next p true ] if find/match address "./" [ remove/part address 2 true ] ] ] append new either #"/" = address/1 [next address] [address] new ] init-progress: func [ address ][ f-status/text: reform ["reading" address " "] show f-status progress: 0 ] show-progress: func [ total bytes /local p ][ p: to-integer (log-2 max 1 bytes) * 2 if 500 > length? f-status/text [ f-status/text: head insert/dup tail copy any [ f-status/text "" ] #"|" max 0 p - progress ] progress: p guard [ show f-status wait 0 ] ] read-net-url: func [ url [url!] /local port buffer data size ready? ][ init-progress url if port: attempt[open/direct url] [ change clear url port/url buffer: make binary! size: to-integer any [ port/locals/headers/content-length 8000 ] set-modes port/sub-port [ lines: false binary: true no-wait: true ] while [ all [ not STOP data: wait [30 port/sub-port] ready?: true data: copy port/sub-port ] ][ append buffer data show-progress size length? buffer ready?: false ] close port ] if ready? [buffer] ] get-resource: func [ address [url! file! none!] type [datatype!] /local redirect raw data pos ][ if not address [return [#[none] #[none]]] ;; find the resource in cache all [ url? address pos: find/skip head cache reduce [address binary!] 3 error? raw: pick pos 3 ] all [ url? address pos: find/skip head cache reduce [address type] 3 error? data: pick pos 3 ] ;; otherwise download the resource redirect: copy address if not found? pos [ STOP: false data: attempt [ all [ raw: any [ raw all [ file? redirect read/binary redirect ] all [ url? redirect read-net-url redirect ] ] data: switch/default type reduce [ binary! [ raw ] image! [ foreach sig signatures/image! [ if find/match raw sig [ image: load raw break/return any [ all [block? image not empty? image image? image/1 image/1] all [image? image image] ] ] ] ] ][ to type raw ] ] ] ;; insert resource into cache, even none! values if (length? cache) > (options/cache-limit * 3) [ remove/part head cache 3 ] repend cache [redirect type data] ] reduce [redirect data] ] ;; gets an attribute value from a tag string get-attribute: func [ tag [tag!] name [string!] /local value ][ parse/all tag [ thru name (value: true) any whitespace #"=" any whitespace [ {"} copy value to {"} | {'} copy value to {'} | copy value [ to { } | to {^/} | to {^-} | to {/} | to {>} ] ] ] value ] ;; gets a reference from a tag string get-ref: func [ tag [tag!] name [string!] /local ref f ][ if ref: get-attribute tag name [ either f: find/match ref "mailto:" [ attempt [to-email f] ][ absolute-address ref ] ] ] html: context [ content: make block! 100 links: make block! 100 flowtext: none element: none ref: none a-ref: none a-text: none a-img: none box: none width: none style: none visible: true ;; generates VID code for a horizontal ruler element insert-hr: does [ if all [visible not box] [ append content compose [ pad 0x12 hrule (1x0 * (max options/min-width width - (2 * options/margin/x)) + 0x1) pad 0x12 ] box: true ] ] ;; generates VID code for a link button insert-link: func [href [url! email!] text [string!] /local text2] [ if all [visible href not empty? href] [ text2: trim/lines decode-entities text if any [not string? text2 empty? text2] [ text2: "(link)" ] f-textwidth/text: text2 append content compose/deep/only [ hyperlink (copy text2 ) (6x6 + size-text f-textwidth ) user-data (copy/deep reduce [href href] ) ] append links copy href box: false ] ] ;; generates VID code for a link image insert-link-image: func [href [url! email!] src [url!] /local image] [ if all [visible not empty? href not empty? src] [ either options/images [ if image: second get-resource src image! [ append content compose/deep/only [ hyperlink-image (image ) (image/size + 4x4 ) user-data (copy/deep reduce [src href] ) ] append links copy href box: false ] ][ insert-link href "(image)" ] ] ] ;; generates VID code for an image insert-image: func [src [url!] /local image] [ if all [visible options/images not empty? src] [ if image: second get-resource src image! [ if image/size = max image/size options/image-minsize [ append content compose/deep/only [ static-image (image ) (image/size + 2x2 ) user-data (copy/deep reduce [src src] ) ] box: false ] ] ] ] ;; generates VID code for text insert-text: does [ if all [visible 1 < length? flowtext] [ append content compose switch/default style [ bold [ [ boldtext (copy flowtext ) (max options/min-width width - (2 * options/margin/x) ) ] ] item [ [ pad 0x6 bullet pad 20x-22 hypertext (copy flowtext ) (max options/min-width width - (2 * options/margin/x) ) pad -20x-6 ] ] pre [ [ pretext (copy flowtext ) (max options/min-width width - (2 * options/margin/x) ) ] ] ][ [ hypertext (copy flowtext ) (max options/min-width width - (2 * options/margin/x) ) ] ] box: false ] clear flowtext ] ;; generates VID code for indentation insert-indent: func [ value [integer!] /local box2 ][ box2: box insert-text if options/indent <> 0 [ append content compose [ indent (options/indent * value) ] ] width: width - (options/indent * value) box: box2 ] ;; tags ==> actions tag-actions: [ opening [<a> <frame> <p> <br> <hr> <img> <table> <tr> <td> <ul> <ol> <dl> <dt> <dd> <li> <h1> <h2> <h3> <h4> <h5> <pre> <form> <script> <object> <style>] [ insert-text ] opening [<form> <script> <object> <style>] [ visible: false ] opening [<b>] [ if all [empty? flowtext style = none] [style: 'bold] ] opening [<title> <h1> <h2> <h3> <h4> <h5> <dt>] [ style: 'bold ] opening [<pre>] [ style: 'pre ] opening [<li> <dd>] [ style: 'item ] opening [<hr> <table> <tr>] [ insert-hr ] opening [<table> <ul> <ol> <dl>] [ insert-indent 1 ] opening [<a>] [ a-ref: get-ref element "href" a-img: none clear a-text ] opening [<frame>] [ if a-ref: get-ref element "src" [ insert-link a-ref "(frame)" a-ref: none ] ] opening [<img>] [ either a-ref [ a-img: get-ref element "src" ][ if ref: get-ref element "src" [ insert-image ref ] ] ] closing [<a>] [ if a-ref [ either a-img [ insert-link-image a-ref a-img ][ insert-link a-ref a-text ] a-ref: none ] ] closing [<table> <ul> <ol> <dl>] [ insert-indent -1 if style = 'item [style: none] ] closing [<hr> <table> <tr>] [ insert-hr ] closing [<title> <h1> <h2> <h3> <h4> <h5> <pre> <li> <dt> <dd>] [ insert-text style: none ] closing [<b>] [ if style = 'bold [style: none] ] closing [<form> <script> <object> <style>] [ clear flowtext visible: true ] ] ;; generate a VID layout block from HTML process: func [ html [string!] new-width [integer!] /local tags element tag text sub opening? closing? e ][ content: clear head content links: clear head links flowtext: copy "" a-text: copy "" a-img: a-ref: style: none STOP: false width: new-width tags: load/markup html foreach element tags [ self/element: element if all [ tag? element none? find/match element <!--> parse/all element [ (e: none) opt "/" copy e some alpha-num to end ] ][ e: to-tag lowercase e opening?: #"/" <> first element closing?: any [#"/" = first element #"/" = last element] foreach [type tags code] tag-actions [ if any [ all [opening? type = 'opening] all [closing? type = 'closing] ][ if find tags e [do code] ] ] ] if string? element [ either all [style = 'pre none? a-ref] [ text: decode-entities element append flowtext text ][ if not empty? text: trim/lines decode-entities element [ either a-ref [ repend a-text [" " text] ][ repend flowtext [" " text] ] trim/lines flowtext ] ] ] ] insert-text content ] ] ] SONAR1/init | |
deglingo | 3-Jan-2011/19:58:08+1:00 |
Une merveilleuse année à tous, pleine de bonnes nouvelles du côté Rebol. Je ne suis qu'un piètre utilisateur de Rebol, mais sincèrement bravo à toutes les initiatives de Nicolas. Cela donne envie de continuer à s'accrocher à Rebol. Et, merci pour toutes ces informations sur ce post. Pas mal du tout ce mini-browser en Rebol. Par-contre, cela ne correspond pas tout à fait à mon idée initiale, j'aurai dû être plus précis dès le début, c'est ma faute, désolé ! En fait, je travaille en Java/J2EE en entreprise. Et, j'essaie souvent de voir si ce que l'on fait serait transposable en Rebol. Nous avons : + un catalogue d'articles unique sous la forme d'une 1ère application web (HTML, Javascript, Ajax, CSS, flash, etc...) accessible depuis différents canaux de vente + une application de vente pour des internautes (2ème application web) / 1er canal de vente + une application de vente sous la forme d'un client "riche" Eclipse RCP utilisée dans des magasins, pilotant d'autres applications installées sur chaque poste / 2ème canal de vente Les 2 applications de ventes (web et Eclipse RCP) doivent pouvoir afficher l'unique catalogue d'articles web. Sur chaque fiche article du catalogue web, on trouve un bouton "Ajouter au panier" : + sur l'appli. web de vente, cela déclenche l'ajout dans le panier "web" + sur le client Eclipse RCP, le catalogue web est affiché à l'intérieur d'une fenêtre Eclipse dans le navigateur intégré (un peu comme dans la copie d'écran dans mon 1er post). Comme je l'ai expliqué, le navigateur n'a pas été redéveloppé, et ce n'était pas notre but. C'est le navigateur installé sur le poste (IE6, IE7, Firefox, etc...) qui est utilisé et piloté. Grâce à un "LocationListener" dans Eclipse, on peut capturer des URLs factices du type "vente://ajout_panier?codeArticle=12345", et déclencher l'ajout au panier dans l'application Eclipse RCP à partir d'actions dans le catalogue web. (c'est cette application Eclipse RCP dont j'essaie de voir la transposition en Rebol / R2 View / R3GUI) Le catalogue web est donc mutualisé entre plusieurs canaux/applications de vente. Dans chacune des applis de vente, on bénéficie de tout le rendu d'un des navigateurs du marché et de ses plugins. C'est donc une question d'intégration d'applications au sein d'une entreprise, un cas d'école mais bien réel. @Jocko Selon toi, ce que je décris serait possible en utilisant une extension R3 ? On pourrait récupérer des évènements du navigateur dans Rebol ? grâce au mécanisme de Callbacks ? @Didec C'est OpenGL qui est intégré dans R3GUI, ce n'est plus AGG ? ou les deux ? Merci. | |
Didec | 10-Jan-2011/10:08:49+1:00 |
AGG est toujours intégré dans le Rebol3 de base de RT. Maxim a expérimenté l'intégration d'OpenGL en plus d'AGG via les extensions en C de R3. Il peut donc avoir un rendu OpenGL dans un gob! R3. Je pense que pour l'affichage d'un objet "navigateur" dans une fenêtre R3 (donc dans un gob!) cela doit être possible par une technique similaire. Pour ce qui est des événements, là, je ne sais pas. | |
deglingo | 10-Jan-2011/19:38:24+1:00 |
Merci beaucoup pour l'info. Je serai intéressé pour en savoir un peu plus sur le sujet. En fait, il faudrait arriver : + à ouvrir un objet navigateur (IE, Firefox, etc...) en ayant son rendu graphique dans un gob! R3 + (sous Windows) et, en même temps, à piloter ce navigateur via un lien OLE Par-contre, pour récupérer les évènements du navigateur, je ne sais pas si l'on peut utiliser le lien OLE. Sinon, il n'y a pas une notion d'évènements au niveau des extensions R3 ? | |
trigram | 10-Jan-2011/23:33:06+1:00 |
Le mieu serait d'avoir un update pour Firefox multi-OS du plugin REBOL, non ? | |
deglingo | 10-Jan-2011/23:57:44+1:00 |
En fait, comme j'expliquais dans mon 1er post sur ce sujet, mon besoin est en quelque sorte l'inverse du plugin Rebol. Je voudrais savoir comment l'on pourrait utiliser tout le potentiel d'un des navigateurs du marché (HTML, Javascript, CSS, Flash, Ajax, etc...), mais en affichant son rendu graphique dans une fenêtre Rebol. Comme le suggère Didec, il faudrait sans doute descendre au niveau gob!. Eclipse RCP le fait par exemple très bien avec son composant SWT Browser utilisable sur tous les OS. Je souhaiterai pouvoir également réagir dans le code Rebol sur les évènements venant du navigateur (exemple d'évènements sur IE : http://msdn.microsoft.com/en-us/library/aa752084(v=vs.85).aspx ). J'ai expliqué plus haut le besoin derrière tout ça. C'est un cas que je rencontre dans mon boulot : l'intégration d'1 nouvelle application web dans un client riche Eclipse RCP existant. J'essayai de voir si l'on pouvait faire la même chose dans un client graphique Rebol. | |
trigram | 11-Jan-2011/0:32:29+1:00 |
A mon avis c'est pas gagné. Je peux juste répéter qu'en Delphi tu pouvais importer IE et l'utiliser comme un composant standard Delphi. Comme faire en Rebol ??? Gob! c'est du Rebol3 il me semble... Si un moteur de rendu HTML digne de ce nom existait en REBOL se serait un sacré pied de nez aux browsers actuels avec leur dizaine voir centaine de Mo... Ou alors, il faudrait faire le JRebol dont a parlé ou un MRebol ou encore REBOL.NET et pouvoir utiliser les librairies graphiques standard Java, Mono ou . NET Je m'enlise... R2 : non, sauf à repartir de Sonar et de le faire évoluer et d'accepter un truc un peu beaucoup moins jolie... après il faudra traiter le code Javascript... Il y a bien un début de tentative de Janko... Voir autre topic sur VID Web... R3 : a priori possible grâce aux Gob! Nico | |
deglingo | 11-Jan-2011/21:42:25+1:00 |
Non, je sais bien qu'un moteur de rendu HTML/Javascript/CSS/Flash digne d'un navigateur du marché n'existe pas en Rebol. Justement, mon but serait de ne pas re-développer la roue, mais d'en piloter un existant en Rebol (IE, Firefox, etc...), comme le fait SWT/Eclipse RCP : + http://www.eclipse.org/articles/Article-SWT-browser-widget/browser.html + http://www.vogella.de/blog/2009/12/21/javascript-swt/ + http://www.itaware.eu/2007/07/15/interaction-between-web-and-desktop-application/ Oui, le gob! est un type R3 (Graphical Object). Il faudrait voir si cela est possible dans ce type d'objet graphique bas niveau. J'ai l'impression peut-être complètement fausse (vous me direz), qu'en Rebol, on veut souvent re-développer des choses existantes de A à Z, comme refaire un moteur de rendu HTML/CSS/Javascript/Flash. C'est sans doute très intéressant comme projet surtout avec un "méta-langage" comme Rebol. Mais, pourquoi ne pas penser INTEGRATION avec des outils/technos existantes dans certains cas ? | |
deglingo | 11-Jan-2011/21:59:51+1:00 |
L'adoption massive d'un langage passe, entre autres, par sa capacité à intégrer ou à s'interconnecter avec des technos existantes. Avec Rebol, on a l'impression que c'est vrai. Le langage intègre tous les protocoles réseau de base. On peut même en développer de nouveaux. On peut se connecter à des bases de données MySQL, Oracle, etc... Mais, est-ce si vrai que cela ? | |
rebolfrance | 12-Jan-2011/1:04:34+1:00 |
A mon avis, je peux rajouter un nouveau sujet à traiter : le Mashup. Il faudrait voir si avec le module d'appel aux DLLs on arriverait à faire quelque chose pour sous-traiter le travail d'évaluation du Javascript par exemple... REBOL aurait eu une carte à jouer sur ce terrain du Mashup parce que c'est du parsing de page, de l'intégration entre différentes applis... Aujourd'hui, pour faire du Mashup, on a en plus besoin d'un moteur/interpréteur Javascript. Si on souhaite faire quelque chose sur le sujet. Nico | |
shadwolf | 13-Jan-2011/12:38:27+1:00 |
c'est d'autant plus compliqué que rebol cherche a redéfinir l'informatique de nos jours plus qu'à s'interfacer avec. Quel interet d'avoir un module webkit dans rebol ? au final c'est pas ce qui assurera que vous pourrez etendre rebolesquement votre code existant sans avoir a y toucher. Peut on faire une traduction de webkit en rebol ? Oui se serait un travail collossal qui necessiterait un travail a plein temps. Tout cet immense travail a t'il un intéret je veux dire en quoi un navigateur rebolesque aurait une utilité ? Si le but final est de shinté les interfaces ajax pour les étendre et les rendre plus sympatiques avec du code rebol on transformerait notre solution web based et donc relativement passe partout en une solution inter dépendante de rebol. en l'etat actuel de rebol est ce souhaitable ? | |
trigram | 13-Jan-2011/18:47:43+1:00 |
Pas besoin de la partie rendu graphique. Juste la partie qui prend en compte les aspects javascript. La question est plutôt : peut-on faire un appel à un module externe et récupérer le résultat en REBOL ? inter-agir avec Webkit ? | |
Login required to Post. |