21 define LEFT_MARGIN = 10;
22 define RIGHT_MARGIN = 10;
23 define TOP_MARGIN = 10;
24 define BOTTOM_MARGIN = 10;
26 enum VerticalAlignment { middle, top, bottom };
28 enum HorizontalAlignment { none, left, middle, right };
30 define CELL_SPACING = 0;
32 class RenderFlags { bool lineW:1,width:1,render:1,minW:1; };
34 enum InputType { text, submit, radio, hidden };
36 class ImageEntry : struct
38 ImageEntry prev, next;
51 bitmapPtrs.Free(null);
55 class FontEntry : struct
69 class RequestLink : OldLink
74 class AlignedObject : struct
76 AlignedObject prev, next;
82 static HTMLView browserWindow;
84 class ObjectThread : Thread
86 bool objectThreadDead;
87 bool objectThreadTerminate;
88 Semaphore objectThreadSemaphore {};
92 objectThreadDead = false;
93 for(;!objectThreadTerminate;)
95 if(objectRequests.first)
99 //((GuiApplication)__thisModule).Lock();
101 for(;!objectThreadTerminate;)
106 char path[MAX_LOCATION], referer[MAX_LOCATION];
109 for(request = objectRequests.first; request && request.processed; request = (RequestLink)request.next);
112 request.processed = true;
113 objectsMutex.Release();
116 entry = request.data;
118 strcpy(path, entry.src);
119 //strcpy(referer, browserWindow.location ? browserWindow.location : "");
120 strcpy(referer, entry.referer); //browserWindow.location ? browserWindow.location : "");
122 //((GuiApplication)__thisModule).Unlock();
124 if(path && strstr(path, "http://") == path)
126 HTTPFile httpFile {};
128 //printf("Opening URL\n");
130 //((GuiApplication)__thisModule).PauseNetworkEvents();
131 if(httpFile.OpenURL(path, referer, null))
133 char extension[MAX_EXTENSION];
134 entry.bitmap = Bitmap { alphaBlend = true };
135 //printf("Loading File\n");
136 entry.bitmap.LoadFromFile(file, GetExtension(path, extension), null);
140 entry.missing = true;
141 //((GuiApplication)__thisModule).ResumeNetworkEvents();
145 file = FileOpen(path, read);
147 entry.missing = true;
150 char extension[MAX_EXTENSION];
151 entry.bitmap = Bitmap { alphaBlend = true };
152 entry.bitmap.LoadFromFile(file, GetExtension(path, extension), null);
158 objectRequests.Remove(request);
160 objectsMutex.Release();
162 ((GuiApplication)__thisModule).Lock();
163 if(!objectThreadTerminate)
166 Window rootWindow = browserWindow.rootWindow;
168 display = rootWindow.parent.display;
170 display = rootWindow.display;
175 entry.bitmap.MakeDD(browserWindow.displaySystem);
176 if(entry.bitmap && entry.bitmap.alphaBlend)
178 entry.bitmap.Convert(null, pixelFormat888, null);
179 // entry.bitmap.displaySystem = displaySystem;
182 for(bitmapPtr = entry.bitmapPtrs.first; bitmapPtr; bitmapPtr = bitmapPtr.next)
184 *((Bitmap*) bitmapPtr.data) = entry.bitmap;
186 browserWindow.ComputeMinSizes();
187 browserWindow.ComputeSizes();
188 browserWindow.PositionForms();
189 browserWindow.Update(null);
191 // ((GuiApplication)__thisModule).UpdateDisplay();
194 // TRIED MOVING THIS HERE BECAUSE OF printf("bug") in GuiApplication if(window.display.current)
195 ((GuiApplication)__thisModule).UpdateDisplay();
197 ((GuiApplication)__thisModule).Unlock();
199 //((GuiApplication)__thisModule).Unlock();
203 //printf("Waiting for Object Thread Semaphore\n");
204 objectThreadSemaphore.Wait();
207 objectThreadDead = true;
212 static ObjectThread objectThread1 { };
213 static ObjectThread objectThread2 { };
214 static ObjectThread objectThread3 { };
215 static ObjectThread objectThread4 { };
216 static Mutex objectsMutex {};
217 static OldList imageCache;
218 /*static */OldList fontCache;
220 static OldList objectRequests;
222 static void WriteBlock(File f, Block block)
224 static int indent = 0;
228 for(c = 0; c<indent; c++)
234 f.Printf("Text: %s\n", block.text);
237 f.Printf("Image: %d %d %s\n", block.w, block.h, block.src);
246 f.Printf("Anchor: %s\n", block.src);
249 f.Printf("Font: %s, %d\n", block.face, block.size);
252 f.Printf("Center\n");
265 for(child = block.subBlocks.first; child; child = child.next)
268 WriteBlock(f, child);
273 static void ComputeImageSize(Block block)
277 if(block.type == IMAGE)
280 block.w = block.width;
282 block.w = block.bitmap ? block.bitmap.width : 0;
285 block.h = block.height;
287 block.h = block.bitmap ? block.bitmap.height : 0;
289 for(child = block.subBlocks.first; child; child = child.next)
290 ComputeImageSize(child);
293 class HTMLView : Window
296 BitmapResource missing { "<:ecere>emblems/unreadable.png", window = this };
298 Block overLink, clickedLink;
302 void ComputeMinSizes()
306 ComputeImageSize(html.body);
308 // Pre compute some stuff
310 Block block = html.body;
314 Surface surface = display.GetSurface(0,0,null);
317 surface.TextFont(html.defaultFont.font.font);
324 ComputeLine(surface, block, textPos, &nextBlock, &nextTextPos, ¢ered, &w, MAXINT, 0, RenderFlags { minW = true }, 0, null, null, null, true, 0, LEFT_MARGIN);
326 textPos = nextTextPos;
334 void Clear(Block block)
338 if(block.type != TABLE && block.type != IMAGE)
343 if(block.type == TABLE)
345 block.columns.Free(null);
347 if(block.type != IMAGE)
353 block.rowSpan = block.span = 1;
356 for(b = block.subBlocks.first; b; b = b.next)
363 int width = clientSize.w;
364 int height = clientSize.h;
365 Block block = html.body;
366 int totalWidth = 0, totalHeight = 0;
370 Surface surface = display.GetSurface(0,0,null);
373 width = parent.clientSize.w;
375 height = parent.clientSize.h;
379 int maxH = height - BOTTOM_MARGIN;
382 surface.TextFont(html.defaultFont.font.font);
388 int maxW = width - (LEFT_MARGIN + RIGHT_MARGIN);
391 newH = ComputeLine(surface, block, textPos, &nextBlock, &nextTextPos, ¢ered, &w, maxW, maxH - y, RenderFlags { lineW = true, width = true }, 0, null, null, &changeLine, true, y, LEFT_MARGIN);
398 textPos = nextTextPos;
400 totalWidth = Max(totalWidth, w);
404 totalHeight = y + BOTTOM_MARGIN;
405 totalWidth += LEFT_MARGIN + RIGHT_MARGIN;
407 SetScrollArea(totalWidth, totalHeight, false);
408 SetScrollArea(totalWidth, totalHeight, false);
411 if(!initSize.w || !initSize.h)
412 clientSize = Size {!initSize.w ? totalWidth : clientSize.w, !initSize.h ? totalHeight : clientSize.h };
415 void CreateForms(Block block)
419 if(block.type == INPUT)
421 switch(block.inputType)
424 block.window = Button { this, text = block.value, position = Point { 10, 50 }, id = (int64)block, NotifyClicked = ButtonClicked, isDefault = true };
425 eInstance_IncRef(block.window);
426 block.window.Create();
427 block.window.cursor = ((GuiApplication)__thisModule).GetCursor(arrow);
428 //if(!html.defaultButton) html.defaultButton = block.window;
431 block.window = Button { this, isRadio = true, position = Point { 10, 100 }, id = (int64)block, NotifyClicked = ButtonClicked };
432 eInstance_IncRef(block.window);
433 block.window.Create();
434 block.window.cursor = ((GuiApplication)__thisModule).GetCursor(arrow);
437 block.window = EditBox { this, position = Point { 10, 20 }, id = (int64)block };
438 eInstance_IncRef(block.window);
439 block.window.Create();
442 /*if(!activeChild && block.window)
443 block.window.Activate();*/
446 for(child = block.subBlocks.last; child; child = child.prev)
450 void LoadGraphics(Block block, void **previous)
454 if(block.src && (block.type == IMAGE || block.type == TD || block.type == TABLE))
456 char path[MAX_LOCATION];
459 strcpy(path, location ? location : "");
460 if(location && path[strlen(path)-1] != '/')
462 if(block.src[0] == '/' && block.src[1] == '/')
464 strcpy(path, "http:");
465 strcat(path, block.src);
468 PathCat(path, block.src);
470 for(entry = imageCache.first; entry; entry = entry.next)
471 if(!strcmp(entry.src, path))
476 entry = ImageEntry { src = CopyString(path), referer = CopyString(location) };
477 imageCache.Add(entry);
480 block.imageEntry = entry;
481 block.entryPtr = OldLink { data = &block.bitmap };
482 entry.bitmapPtrs.Add(block.entryPtr);
485 block.bitmap = entry.bitmap;
488 if(path && strstr(path, "http://") == path)
492 for(request = objectRequests.first; request; request = (RequestLink)request.next)
494 if(request.data == entry)
499 request = RequestLink { data = entry };
500 objectRequests.Insert(*previous, request);
502 objectThread1.objectThreadSemaphore.Release();
503 objectThread2.objectThreadSemaphore.Release();
504 objectThread3.objectThreadSemaphore.Release();
505 objectThread4.objectThreadSemaphore.Release();
507 else if(*previous != request)
509 objectRequests.Move(request, *previous);
512 objectsMutex.Release();
516 // ADDED THIS TO LOAD LOCAL FILES RIGHT HERE...
518 File file = FileOpen(path, read);
520 entry.missing = true;
523 char extension[MAX_EXTENSION];
524 entry.bitmap = Bitmap { alphaBlend = true };
525 entry.bitmap.LoadFromFile(file, GetExtension(path, extension), null);
528 for(bitmapPtr = entry.bitmapPtrs.first; bitmapPtr; bitmapPtr = bitmapPtr.next)
530 *((Bitmap*) bitmapPtr.data) = entry.bitmap;
532 block.bitmap = entry.bitmap;
535 block.font = block.parent.font;
537 else if(block.type == FONT || block.type == ANCHOR)
540 for(entry = fontCache.first; entry; entry = entry.next)
542 if(!strcmpi(entry.face, block.face) &&
543 entry.size == block.size &&
544 entry.attribs == block.attribs)
552 entry = FontEntry { /*font = displaySystem.LoadFont(block.face, block.size, block.attribs), */size = block.size, attribs = block.attribs, face = CopyString(block.face) };
553 fontCache.Add(entry);
563 else if(block.parent)
564 block.font = block.parent.font;
566 for(child = block.subBlocks.first; child; child = child.next)
567 LoadGraphics(child, previous);
570 bool OnLoadGraphics()
574 for(entry = imageCache.first; entry; entry = entry.next)
576 entry.bitmap.MakeDD(displaySystem);
577 if(entry.bitmap && entry.bitmap.alphaBlend)
579 entry.bitmap.Convert(null, pixelFormat888, null);
580 // entry.bitmap.displaySystem = displaySystem;
583 for(fEntry = fontCache.first; fEntry; fEntry = fEntry.next)
584 fEntry.font = browserWindow.displaySystem.LoadFont(fEntry.face, fEntry.size, fEntry.attribs);
588 void OnUnloadGraphics()
591 for(entry = fontCache.first; entry; entry = entry.next)
593 browserWindow.displaySystem.UnloadFont(entry.font);
598 void NormalizeSelection(Block * startBlock, int * startSel, Block * endBlock, int * endSel)
600 bool selAfter = false;
602 for(b = selBlock; b; b = GetNextBlock(b))
604 if(b != selBlock && b == textBlock)
611 if(textBlock == selBlock)
613 *startSel = Min(selPosition, curPosition);
614 *endSel = Max(selPosition, curPosition);
615 *startBlock = *endBlock = textBlock;
619 *startBlock = textBlock;
620 *startSel = curPosition;
621 *endSel = selPosition;
622 *endBlock = selBlock;
626 *startBlock = selBlock;
627 *startSel = selPosition;
628 *endSel = curPosition;
629 *endBlock = textBlock;
635 Block block = html.body;
639 int maxH = clientSize.h - BOTTOM_MARGIN;
640 OldList leftObjects { };
641 OldList rightObjects { };
642 AlignedObject object, nextObject;
645 Surface surface = display.GetSurface(0,0,null);
648 surface.TextFont(html.defaultFont.font.font);
656 int thisLineCentered = centered;
657 Font font = surface.GetFont();
661 right = clientSize.w - RIGHT_MARGIN;
663 for(object = leftObjects.last; object; object = nextObject)
665 nextObject = object.prev;
666 if(y < object.untilY || object.next)
669 leftObjects.Delete(object);
671 for(object = rightObjects.last; object; object = nextObject)
673 nextObject = object.prev;
674 if(y < object.untilY || object.next)
677 rightObjects.Delete(object);
679 right = Max(left, right);
682 newH = ComputeLine(surface, block, textPos, &nextBlock, &nextTextPos, ¢ered, &w, maxW, maxH - y, RenderFlags {}, y, &leftObjects, &rightObjects, &changeLine, true, 0 /*y*/, LEFT_MARGIN);
684 x = Max(left,(left + right - w) / 2);
688 surface.TextFont(font);
690 PositionLine(this, surface, x - scroll.x, y - scroll.y,
691 maxW, newH, block, textPos, nextBlock, nextTextPos,
692 left - scroll.x, right - scroll.x);
700 textPos = nextTextPos;
706 void Open(char * location, char * firstReferer)
709 char referer[MAX_LOCATION] = "";
710 char relocation[MAX_LOCATION];
713 strcpy(relocation, location);
715 if(strstr(location, "http://") != location)
717 if(!FileExists(location))
719 strcpy(relocation, "http://");
720 strcat(relocation, location);
725 f = (HTTPFile)FileOpen(location, read);
735 strcpy(referer, firstReferer);
740 SetScrollArea(0,0,0);
745 char path[MAX_LOCATION];
748 delete this.location;
749 this.location = CopyString(relocation);
750 fileName = this.location;
751 ((GuiApplication)__thisModule).UpdateDisplay();
753 if(!(opened = f.OpenURL(this.location, referer, relocation)) && !strcmp(this.location, relocation))
758 //printf("Relocated to %s\n", relocation);
760 strcpy(referer, this.location);
762 // Fix up relocation relative paths
763 strcpy(path, this.location);
764 if(path[strlen(path)-1] != '/')
766 if(relocation[0] == '/' && relocation[1] == '/')
768 strcpy(path, "http:");
769 strcat(path, relocation);
772 PathCat(path, relocation);
773 strcpy(relocation, path);
776 delete this.location;
777 this.location = CopyString(relocation);
778 fileName = this.location;
782 void * previous = null;
784 LoadGraphics(html.defaultFont, &previous);
785 LoadGraphics(html.block, &previous);
786 CreateForms(html.block);
795 File f = FileOpen("debug2.txt", write);
798 WriteBlock(f, html.body);
806 NotifyPageOpened(master);
809 void OpenFile(File f, char * firstReferer)
811 char referer[MAX_LOCATION] = "";
812 char relocation[MAX_LOCATION];
820 strcpy(referer, firstReferer);
825 SetScrollArea(0,0,0);
829 this.location = null;
830 fileName = this.location;
834 void * previous = null;
836 LoadGraphics(html.defaultFont, &previous);
837 LoadGraphics(html.block, &previous);
838 CreateForms(html.block);
845 File f = FileOpen("debug2.txt", write);
848 WriteBlock(f, html.body);
854 NotifyPageOpened(master);
857 bool ScrollToAnchor(Block block, char * anchor)
860 if(block.type == ANCHOR && block.anchor && !strcmpi(block.anchor, anchor))
862 SetScrollPosition(0, block.startY);
868 for(subBlock = block.subBlocks.first; subBlock; subBlock = subBlock.next)
870 if((result = ScrollToAnchor(subBlock, anchor)))
877 bool GoToAnchor(char * anchor)
879 return anchor ? ScrollToAnchor(html.block, anchor) : false;
882 virtual bool Window::NotifyPageOpened();
886 objectThread1.objectThreadTerminate = true;
887 objectThread2.objectThreadTerminate = true;
888 objectThread3.objectThreadTerminate = true;
889 objectThread4.objectThreadTerminate = true;
890 ((GuiApplication)__thisModule).Unlock();
891 objectThread1.objectThreadSemaphore.Release();
892 objectThread2.objectThreadSemaphore.Release();
893 objectThread3.objectThreadSemaphore.Release();
894 objectThread4.objectThreadSemaphore.Release();
897 while(!objectThread1.objectThreadDead ||
898 !objectThread2.objectThreadDead ||
899 !objectThread3.objectThreadDead ||
900 !objectThread4.objectThreadDead)
902 // ((GuiApplication)__thisModule).ProcessNetworkEvents();
906 //objectThread.Wait();
907 objectRequests.Free(null);
909 ((GuiApplication)__thisModule).Lock();
914 browserWindow = this;
915 objectThread1.objectThreadTerminate = false;
916 objectThread2.objectThreadTerminate = false;
917 objectThread3.objectThreadTerminate = false;
918 objectThread4.objectThreadTerminate = false;
920 objectThread1.Create();
921 objectThread2.Create();
922 objectThread3.Create();
923 objectThread4.Create();
928 location = CopyString(location);
937 Open(location, null);
941 void OnResize(int width, int height)
951 // For text selection
952 Block textBlock, selBlock;
953 int curPosition, selPosition;
954 bool isSelected; // Persistent state changed by RenderLine
956 void OnRedraw(Surface surface)
958 Block block = html.body;
962 int maxH = clientSize.h - BOTTOM_MARGIN;
963 OldList leftObjects { };
964 OldList rightObjects { };
966 AlignedObject object, nextObject;
969 surface.SetBackground(html.background);
970 if(html.background.a < 255)
971 surface.Area(0,0,clientSize.w,clientSize.h);
973 surface.Clear(colorBuffer);
974 if(html.defaultFont.font) // TOFIX: Null! (No font set?)
975 surface.TextFont(html.defaultFont.font.font);
976 surface.SetForeground(html.defaultFont.textColor);
986 int thisLineCentered = centered;
987 Font font = surface.GetFont();
991 right = clientSize.w - RIGHT_MARGIN;
993 for(object = leftObjects.last; object; object = nextObject)
995 nextObject = object.prev;
996 if(y < object.untilY || object.next)
999 leftObjects.Delete(object);
1001 for(object = rightObjects.last; object; object = nextObject)
1003 nextObject = object.prev;
1004 if(y < object.untilY || object.next)
1007 rightObjects.Delete(object);
1009 right = Max(left, right);
1010 maxW = right - left;
1012 newH = ComputeLine(surface, block, textPos, &nextBlock, &nextTextPos, ¢ered, &w, maxW, maxH - y, RenderFlags {}, y, &leftObjects, &rightObjects, &changeLine, false, 0, 0);
1013 if(thisLineCentered)
1014 x = Max(left,(left + right - w) / 2);
1018 surface.TextFont(font);
1021 RenderLine(this, surface, x - scroll.x, y - scroll.y, maxW, newH, block, textPos, nextBlock, nextTextPos, left - scroll.x, right - scroll.x);
1030 textPos = nextTextPos;
1035 void OnVScroll(ScrollBarAction action, int position, Key key)
1040 bool OnKeyHit(Key key, unichar character)
1045 CycleChildren(true, false, false, true);
1048 CycleChildren(false, false, false, true);
1050 case left: case right:
1051 horzScroll.OnKeyHit(key, character);
1053 case down: case up: case pageDown: case pageUp:
1054 vertScroll.OnKeyHit(key, character);
1060 bool OnKeyDown(Key key, unichar character)
1066 vertScroll.OnKeyDown(home, character);
1067 horzScroll.OnKeyDown(home, character);
1072 vertScroll.OnKeyDown(end, character);
1073 horzScroll.OnKeyDown(end, character);
1080 void OnHScroll(ScrollBarAction action, int position, Key key)
1085 bool PickHTML(int pickX, int pickY, Block* pickBlock, int * pickTextPos)
1087 bool result = false;
1088 Block block = html.body;
1092 int maxH = clientSize.h - BOTTOM_MARGIN;
1093 OldList leftObjects { };
1094 OldList rightObjects { };
1095 AlignedObject object, nextObject;
1098 Surface surface = display.GetSurface(0,0,null);
1101 if(html.defaultFont.font) // TOFIX: Null! (No font set?)
1102 surface.TextFont(html.defaultFont.font.font);
1110 int thisLineCentered = centered;
1111 Font font = surface.GetFont();
1115 right = clientSize.w - RIGHT_MARGIN;
1117 for(object = leftObjects.last; object; object = nextObject)
1119 nextObject = object.prev;
1120 if(y < object.untilY || object.next)
1123 leftObjects.Delete(object);
1125 for(object = rightObjects.last; object; object = nextObject)
1127 nextObject = object.prev;
1128 if(y < object.untilY || object.next)
1131 rightObjects.Delete(object);
1133 right = Max(left, right);
1134 maxW = right - left;
1136 newH = ComputeLine(surface, block, textPos, &nextBlock, &nextTextPos, ¢ered, &w, maxW, maxH - y, RenderFlags {}, y, &leftObjects, &rightObjects, &changeLine, false, 0, 0);
1137 if(thisLineCentered)
1138 x = Max(left,(left + right - w) / 2);
1142 surface.TextFont(font);
1144 if(PickLine(this, surface, x - scroll.x, y - scroll.y,
1145 maxW, newH, block, textPos, nextBlock, nextTextPos,
1146 left - scroll.x, right - scroll.x, pickX, pickY, pickBlock, pickTextPos))
1158 textPos = nextTextPos;
1165 bool OnMouseMove(int x, int y, Modifiers mods)
1167 Block pickBlock = null;
1168 Block linkBlock = null;
1169 int pickTextPos = 0;
1171 if(!mods.isSideEffect)
1173 PickHTML(x,y, &pickBlock, &pickTextPos);
1177 for(linkBlock = pickBlock; linkBlock; linkBlock = linkBlock.parent)
1179 if(linkBlock.type == ANCHOR)
1185 if(strstr(linkBlock.href, "edit://") == linkBlock.href)
1186 cursor = ((GuiApplication)__thisModule).GetCursor(iBeam);
1188 cursor = ((GuiApplication)__thisModule).GetCursor(hand);
1189 overLink = linkBlock;
1193 if(pickBlock && pickBlock.type == TEXT)
1195 cursor = ((GuiApplication)__thisModule).GetCursor(iBeam);
1199 cursor = ((GuiApplication)__thisModule).GetCursor(arrow); //null);
1203 overBlock = pickBlock;
1204 overPos = pickTextPos;
1209 bool OnLeftButtonDown(int x, int y, Modifiers mods)
1211 OnMouseMove(x, y, mods);
1214 clickedLink = overLink;
1221 virtual bool OnOpen(char * href)
1223 char newLocation[MAX_LOCATION];
1225 strcpy(newLocation, location ? location : "");
1226 if(newLocation[strlen(newLocation)-1] != '/')
1227 PathCat(newLocation, "..");
1228 if(href[0] == '/' && href[1] == '/')
1230 strcpy(newLocation, "http:");
1231 strcat(newLocation, href);
1234 PathCat(newLocation, href);
1236 Open(newLocation, null);
1240 bool OnLeftButtonUp(int x, int y, Modifiers mods)
1245 if(clickedLink == overLink && clickedLink.href)
1247 if(OnOpen(clickedLink.href))
1254 void AddFormControls(char * location, Block block)
1257 if(block.type == INPUT)
1259 switch(block.inputType)
1269 if(location[strlen(location)-1] != '?')
1271 strcat(location, "&");
1273 strcat(location, block.name);
1274 strcat(location, "=");
1276 len = strlen(location);
1278 text = ((EditBox)block.window).contents;
1280 for(c = 0; text[c]; c++)
1283 location[len++] = '+';
1286 location[len++] = text[c];
1289 location[len] = '\0';
1295 for(child = block.subBlocks.first; child; child = child.next)
1297 AddFormControls(location, child);
1301 bool ButtonClicked(Button button, int x, int y, Modifiers mods)
1303 Block block = (Block)button.id;
1304 if(block.inputType == submit)
1308 for(formBlock = block; formBlock; formBlock = formBlock.parent)
1309 if(formBlock.type == FORM)
1312 if(formBlock && formBlock.action)
1314 char newLocation[MAX_LOCATION];
1316 strcpy(newLocation, location);
1317 if(newLocation[strlen(newLocation)-1] != '/')
1318 PathCat(newLocation, "..");
1320 if(formBlock.action[0] == '/' && formBlock.action[1] == '/')
1322 strcpy(newLocation, "http:");
1323 strcat(newLocation, formBlock.action);
1326 PathCat(newLocation, formBlock.action);
1327 strcat(newLocation, "?");
1331 strcat(newLocation, block.name);
1332 strcat(newLocation, "=");
1335 AddFormControls(newLocation, formBlock);
1337 Open(newLocation, null);
1347 html.background = white;
1352 delete this.location;
1356 FontEntry fontEntry;
1357 while((entry = imageCache.first))
1359 imageCache.Remove(entry);
1362 while((fontEntry = fontCache.first))
1364 fontCache.Remove(fontEntry);
1367 html.block.ClearEntries();
1371 property char * location
1377 location = CopyString(value);
1379 Open(location, null);
1381 get { return location; }