Annotation of libwww/Library/src/HTHist.c, revision 2.3
2.1 frystyk 1: /* HTHist.c
2: ** NAVIGATION MANAGER
3: **
2.2 frystyk 4: ** (c) COPYRIGHT MIT 1995.
2.1 frystyk 5: ** Please first read the full copyright statement in the file COPYRIGH.
2.3 ! frystyk 6: **
! 7: ** A simple linear history list manager. The manager can only operate
! 8: ** with _one_ linear list. A tree structure would be nice!
2.1 frystyk 9: */
10:
11: /* Library include files */
12: #include "tcp.h"
13: #include "HTUtils.h"
2.3 ! frystyk 14: #include "HTAnchor.h"
! 15: #include "HTHist.h" /* Implemented here */
2.1 frystyk 16:
2.3 ! frystyk 17: PRIVATE HTList * HTHistory = NULL; /* List of visited anchors */
2.1 frystyk 18:
2.3 ! frystyk 19: /* ------------------------------------------------------------------------- */
2.1 frystyk 20:
2.3 ! frystyk 21: /* Record an entry in the list
! 22: ** ---------------------------
! 23: ** Registers the object in the linear list. The first entry is the
! 24: ** home page. No check is done for duplicates.
! 25: ** Returns YES if OK, else NO
2.1 frystyk 26: */
2.3 ! frystyk 27: PUBLIC BOOL HTHistory_record ARGS1(HTAnchor *, destination)
2.1 frystyk 28: {
2.3 ! frystyk 29: if (destination) {
! 30: if (!HTHistory)
! 31: HTHistory = HTList_new();
! 32: return HTList_addObject(HTHistory, destination);
! 33: }
! 34: return NO;
2.1 frystyk 35: }
36:
2.3 ! frystyk 37: /* Delete an entry
! 38: ** ---------------
! 39: ** Deletes the object from the list
! 40: ** Returns YES if OK, else NO
2.1 frystyk 41: */
2.3 ! frystyk 42: PUBLIC BOOL HTHistory_delete ARGS1(HTAnchor *, old)
2.1 frystyk 43: {
2.3 ! frystyk 44: return (HTHistory ? HTList_removeObject(HTHistory, old) : NO);
2.1 frystyk 45: }
46:
2.3 ! frystyk 47: /* Clear the History list
! 48: ** ----------------------
! 49: ** Deletes the history list FROM the last entered occurance of the
! 50: ** current entry and forward.
! 51: ** Returns YES if OK, else NO
! 52: */
! 53: PUBLIC BOOL HTHistory_clearFrom ARGS1 (HTAnchor *, cur)
! 54: {
! 55: if (HTHistory && cur) {
! 56: while (!HTList_isEmpty(HTHistory) && HTList_lastObject(HTHistory)!=cur)
! 57: HTList_removeLastObject(HTHistory);
! 58: return YES;
! 59: }
! 60: return NO;
2.1 frystyk 61: }
62:
2.3 ! frystyk 63: /* Clear the History list
! 64: ** ----------------------
! 65: ** Deletes the history list FROM the entry at position 'cur'. Home page
! 66: ** has position 1.
! 67: ** Returns YES if OK, else NO
! 68: */
! 69: PUBLIC BOOL HTHistory_clearFromPos ARGS1 (int, ind)
! 70: {
! 71: if (HTHistory && ind>=0) {
! 72: HTAnchor *cur = (HTAnchor *)
! 73: (HTList_objectAt(HTHistory, HTList_count(HTHistory) - ind));
! 74: while (!HTList_isEmpty(HTHistory) && HTList_lastObject(HTHistory)!=cur)
! 75: HTList_removeLastObject(HTHistory);
! 76: return YES;
! 77: }
! 78: return NO;
! 79: }
2.1 frystyk 80:
2.3 ! frystyk 81: /* Delete the whole list
! 82: ** ---------------------
! 83: ** Deletes the whole list from memory, so a new list can be started
! 84: ** Returns YES if OK, else NO
! 85: */
! 86: PUBLIC BOOL HTHistory_clearAll NOARGS
2.1 frystyk 87: {
2.3 ! frystyk 88: if (HTHistory) {
! 89: HTList_delete(HTHistory);
! 90: HTHistory = NULL;
! 91: return YES;
2.1 frystyk 92: }
2.3 ! frystyk 93: return NO;
2.1 frystyk 94: }
95:
2.3 ! frystyk 96: /* Number of elements stored
! 97: ** -------------------------
! 98: ** Returns the size of the history list or -1 if none.
! 99: */
! 100: PUBLIC int HTHistory_count NOARGS
2.1 frystyk 101: {
2.3 ! frystyk 102: return (HTHistory ? HTList_count(HTHistory) : -1);
2.1 frystyk 103: }
104:
2.3 ! frystyk 105: /* ------------------------------------------------------------------------- */
! 106: /* NAVIGATION */
! 107: /* ------------------------------------------------------------------------- */
2.1 frystyk 108:
2.3 ! frystyk 109: /* Find and re-register visited anchor
! 110: ** -----------------------------------
! 111: ** Finds already registered anchor with given index and registers it
! 112: ** again EXCEPT if last entry. This allows for `circular' history lists
! 113: ** with duplicate entries.
! 114: */
! 115: PUBLIC HTAnchor * HTHistory_recall ARGS1(int, cnt)
2.1 frystyk 116: {
2.3 ! frystyk 117: HTAnchor *cur = NULL;
! 118: if (HTHistory) {
! 119: cur=(HTAnchor*)HTList_objectAt(HTHistory, HTList_count(HTHistory)-cnt);
! 120: if (cur && cur != HTList_lastObject (HTHistory))
! 121: HTList_addObject (HTHistory, cur);
! 122: }
! 123: return cur;
2.1 frystyk 124: }
125:
2.3 ! frystyk 126: /* Find Indexed entry
! 127: ** ------------------
! 128: ** Entry with the given index in the list (1 is the home page). Like
! 129: ** HTHistory_recall but without re-registration
2.1 frystyk 130: */
2.3 ! frystyk 131: PUBLIC HTAnchor * HTHistory_findPos ARGS1(int, n)
! 132: {
! 133: return (HTHistory ?
! 134: (HTAnchor*)(HTList_objectAt(HTHistory,HTList_count(HTHistory)-n)) :
! 135: NULL);
! 136: }
2.1 frystyk 137:
2.3 ! frystyk 138: /* Can we back in history
! 139: ** ----------------------
! 140: ** Returns YES if the current anchor is not the first entry (home page)
! 141: */
! 142: PUBLIC BOOL HTHistory_canBacktrack ARGS1(HTAnchor *, cur)
! 143: {
! 144: if (HTHistory)
! 145: return (HTList_indexOf(HTHistory, cur) < HTList_count(HTHistory)-1);
! 146: return NO;
! 147: }
2.1 frystyk 148:
2.3 ! frystyk 149: /*
! 150: ** Backtrack with deletion
! 151: ** -----------------------
! 152: ** Returns the previous object and erases the last object. This does not
! 153: ** allow for 'forward' as we are always at the end of the list. If no
! 154: ** previous object exists, NULL is returned so that the application knows
! 155: ** that no previous object was found. See also HTHistory_back().
2.1 frystyk 156: */
2.3 ! frystyk 157: PUBLIC HTAnchor * HTHistory_backtrack NOARGS
2.1 frystyk 158: {
2.3 ! frystyk 159: if (HTHistory && HTList_count(HTHistory) > 1) {
! 160: HTList_removeLastObject (HTHistory);
! 161: return (HTAnchor *) HTList_lastObject (HTHistory);
2.1 frystyk 162: }
2.3 ! frystyk 163: return NULL;
2.1 frystyk 164: }
165:
2.3 ! frystyk 166: /*
! 167: ** Backtrack without deletion
! 168: ** --------------------------
! 169: ** Returns the previos object but does not erase the last object. This
! 170: ** does not allow for 'forward'. If no previous object exists, NULL is
! 171: ** returned so that the application knows that no previous object was
! 172: ** found. See also HTHistory_backtrack()
! 173: */
! 174: PUBLIC HTAnchor * HTHistory_back ARGS1(HTAnchor *, cur)
2.1 frystyk 175: {
2.3 ! frystyk 176: if (HTHistory && HTHistory_canBacktrack(cur)) {
! 177: int pos = HTList_indexOf(HTHistory, cur);
! 178: return ((HTAnchor *) HTList_objectAt(HTHistory, pos + 1));
! 179: }
! 180: return NULL;
2.1 frystyk 181: }
182:
2.3 ! frystyk 183: /* Can we go forward
! 184: ** -----------------
! 185: ** Returns YES if the current anchor is not the last entry
2.1 frystyk 186: */
2.3 ! frystyk 187: PUBLIC BOOL HTHistory_canForward ARGS1(HTAnchor *, cur)
! 188: {
! 189: return (HTHistory && cur && (cur != HTList_lastObject(HTHistory)));
! 190: }
2.1 frystyk 191:
2.3 ! frystyk 192: /*
! 193: ** Forward
! 194: ** -------
! 195: ** Return the next object in the list or NULL if none
2.1 frystyk 196: */
2.3 ! frystyk 197: PUBLIC HTAnchor * HTHistory_forward ARGS1(HTAnchor *, cur)
2.1 frystyk 198: {
2.3 ! frystyk 199: if (HTHistory && HTHistory_canForward(cur)) {
! 200: int pos = HTList_indexOf(HTHistory, cur);
! 201: return ((HTAnchor *) HTList_objectAt(HTHistory, pos - 1));
! 202: }
! 203: return NULL;
2.1 frystyk 204: }
205:
2.3 ! frystyk 206: /*
! 207: ** Can Move By Offset
! 208: ** ------------------
! 209: ** Support for Next and Previous in order to allow for browsing through
! 210: ** the same parent node
2.1 frystyk 211: */
2.3 ! frystyk 212: PUBLIC BOOL HTHistory_canMoveBy ARGS1(int, offset)
! 213: {
! 214: HTAnchor *last = (HTAnchor *) HTList_lastObject(HTHistory);
2.1 frystyk 215:
2.3 ! frystyk 216: /* If we have a last entry and this is a child */
! 217: if (last && last != (HTAnchor *) last->parent) {
! 218: HTList *kids = last->parent->children;
! 219: int cur = HTList_indexOf(kids, last);
! 220: return (HTList_objectAt(kids, cur-(offset)) != NULL);
! 221: }
! 222: return NO;
2.1 frystyk 223: }
224:
2.3 ! frystyk 225: /* Browse through references in the same parent node
! 226: ** -------------------------------------------------
! 227: ** Take the n-th child's link after or before the one we took to get here.
! 228: ** Positive offset means go towards most recently added children or "Next"
! 229: ** and negative value means "Previous"
! 230: */
! 231: PUBLIC HTAnchor * HTHistory_moveBy ARGS1 (int, offset)
2.1 frystyk 232: {
2.3 ! frystyk 233: HTAnchor *last = (HTAnchor *) HTList_lastObject(HTHistory);
! 234:
! 235: /* If we have a last entry and this is a child */
! 236: if (last && last != (HTAnchor *) last->parent) {
! 237: HTList *kids = last->parent->children;
! 238: int cur = HTList_indexOf(kids, last);
! 239: HTAnchor *nextOne = (HTAnchor *) HTList_objectAt (kids, cur-(offset));
! 240: if (nextOne) {
! 241: HTAnchor * destination = HTAnchor_followMainLink(nextOne);
! 242: if (destination) {
! 243: HTList_removeLastObject(HTHistory);
! 244: HTList_removeLastObject (HTHistory);
! 245: HTList_addObject (HTHistory, nextOne);
! 246: HTList_addObject (HTHistory, destination);
! 247: }
! 248: return destination;
! 249: } else {
! 250: if (TRACE)
! 251: fprintf(TDEST,
! 252: "HTHistory... Index out of range %d of list %p.\n",
! 253: offset, (void*)kids);
! 254: }
! 255: }
! 256: return NULL;
2.1 frystyk 257: }
258:
2.3 ! frystyk 259: /* Change last history entry
! 260: ** -------------------------
2.1 frystyk 261: ** Sometimes we load a node by one anchor but leave by a different
262: ** one, and it is the one we left from which we want to remember.
263: */
2.3 ! frystyk 264: PUBLIC void HTHistory_leavingFrom ARGS1 (HTAnchor *, anchor)
2.1 frystyk 265: {
2.3 ! frystyk 266: if (HTHistory) {
! 267: if (HTList_removeLastObject (HTHistory))
! 268: HTList_addObject (HTHistory, anchor);
! 269: }
2.1 frystyk 270: }
Webmaster