This behavior of JS has some implications for how interface code handles things like deletes. The following won't do what one might expect/desire (and my apologies if this is obvious or redundant, but I figure it's worth pointing out):
var item = Scholar.Items.get(1);
Scholar.debug(item);
Scholar.DB.query("DELETE FROM items WHERE itemID=1");
Scholar.Items.reloadAll();
Scholar.debug(item);
The last line will still display the old object, even though _items[1] has been deleted inside Scholar.Items. The following does work, however:
var item = Scholar.Items.get(1);
Scholar.debug(item);
Scholar.DB.query("DELETE FROM items WHERE itemID=1");
Scholar.Items.reloadAll();
var item = Scholar.Items.get(1);
Scholar.debug(item);
Now item is properly undefined. Moral of the story: object references need to be deleted manually after receiving delete notifications, for if external code still has references to deleted data objects, the data layer can't do much about it.
Revised the way the dateAdded and dateModified columns are displayed.
Views are now unregistered on window close.
A few functions in overlay.js were renamed.
Began better commenting of the interface code.
Although I do not yet have interface code for it, collections do not have any sort of setName(), save() functions.
Collections list now implements notify()
Made some fixes on itemTreeView to allow for notify() on multiple deletes
(shifts the row identifier up 1 for each previous delete, etc.)
One more thing -- this might not happen because the tree calls each Item.erase() or Collection.removeItem() individually.
Bug fix on notifier.js so that register*Tree() actually returns the hash. :-)
Unfortunately, unregister*Tree() does not seem to actually work, there is still an object at _observers['itemTree'][hash]
(temporary): When you select an item Scholar no longer loads a page into the browser.
The javascript bugs on those HTML pages were frustrating the debugger.
- Added Notifier triggers to Item.erase() (which only runs if not in a nested transaction) and Collections.erase()
- notify() in ItemTreeView updated with example of taking multiple ids, though it doesn't actually work (and notify() implementations may decide just to refresh the whole tree when ids.length>1 rather than dealing with changes individually)
- When deleting collections, use DB tables that actually exist
Scholar.Notifier framework to handle update notifications between data layer and interface
- Notifier.registerColumnTree(ref) and Notifier.registerItemTree(ref) pass back a unique hash that can be used to unregister the tree later with unregister*(hash) (and must be, lest we leak treeViews and probably entire browser windows if the browser window is closed without unregistering the treeView)
- Data layer calls Scholar.Notify.trigger(event, type, id) after various events (only two calls in the data layer at the moment--more coming later)
- Notify.trigger() calls notify(event, type, id) on all registered trees of the appropriate type -- the data layer usually knows what collection the action pertains to, but we decided that it's cleaner to just let the tree decide what it wants to do rather than add all that logic into the data layer)
(Note: Item collection adds appear to be buggy on the interface side, but removes seem to be working)
Overhauled data access layer to support new model:
- Changed Item.getParent to Item.getCollections() to get ids of parent collections
- Removed Item.setPosition() -- item positions are set internally when items are added to and deleted from collections, but the orderIndex is not currently used or manipulatable externally
- Item constructor/Items.getNewItemByType()/Items.add() no longer take folderID and orderIndex as parameters
- Split getTreeRows() into Scholar.getCollections(parent) and Scholar.getItems(parent), which return root collections or all library items, respectively, if no parent given
- All references to folders in object/method/property names changed to collections
- New methods Collection.addItem(itemID), Collection.hasItem(itemID), Collection.removeItem(itemID)
- Collection.erase() takes optional deleteItems parameter to delete items from DB -- otherwise just removes association and leaves item in library (does, however, delete all descendent collections from DB regardless)
* Note: This will break displaying of items until interface code is updated. *
Scholar.TreeView is now Scholar.FolderTreeView (SourcesTreeView later? depends)
Some changes to the way FolderTreeView works.
New Scholar.ItemGroup -- used by FolderTreeView and ItemTreeView.
the root folder is not currently displayed -- doesn't really matter because we are changing the way it all works.
(note: the Scholar.Items.getAll() function does not seem to be working correctly -- try clicking on the library)
Switching to scholar@chnm.gmu.edu -- SVN folks should rename the text file in their FF profile directories. (Used to be scholar@chnm, so you need to make the change even if you hadn't changed to the GUID yet.) Anyone who's tried the XPI yet will need to reinstall just once from the URL (http://chnm.gmu.edu/firefoxscholar/download/scholar-dev.xpi), as the old version won't find updates with its id.
* Renamed treeView.js to folderTreeView.js (more changes on this file forthcoming) -- this will soon be specifically for folders.
* Added itemTreeView.js, with new Scholar.ItemTreeView class -- specifically for items.
* The items list now supports 3 additional columns: rights, date added, and date modified.
* For now, selecting an item loads the "I'm Feeling Lucky" result of a Google search on the item title.
Added update.rdf for auto-update mechanism (which will get moved out of the extension root by the build system but should stay with a particular tree)
Assigned a new GUID to extension
*** Important: The extension GUID has changed, so you should rename the scholar@chnm text file in your Firefox profile exensions directory to our new GUID "{e007c81c-eb2a-4e1d-b381-d25a45cd11ed}" and restart Firefox ***
More details coming on Basecamp: http://chnm.grouphub.com/W161222
*** Important note: after checking out this code, be sure to delete the compreg.dat and xpti.dat files in your FF profile directory or else the extension will not load. They'll be regenerated when you start FF again, and you won't have to do it again unless we add interfaces or other components. Once I set up the XPI packaging system, this step won't be necessary. ***
- Localization properties are now loaded directly via nsIStringBundleService and available via Scholar.getString(name) -- removed stringbundle from XUL
- Updated status line in bottom right to reflect whether Scholar is loaded correctly or not (temporary, obviously)
Scholar.Folder.erase() -- deletes a folder and all descendent folders and items
Scholar.Folder._getDescendents() - returns an array of descendent folders and items (rows of 'id' and 'isFolder') ("private" for now--could be useful as public later)
Scholar.Folders.unload() - clear folder from internal cache (used by Scholar.Folder.erase())
DB transactions are now automatically nested if beginTransaction() is called when one is already in progress -- the queries aren't committed until the outermost commitTransaction() is called, which is handy for calling methods with their own transactions inside others when the entire process should be a transaction (e.g. Folder.erase() calling Item.erase() for the folder's descendents). Rollbacks are a little trickier -- currently, a rollback in a nested transaction flags the entire transaction for rollback when the outermost commit is reached, which for our purposes will probably be fine.
ScholarLocalizedStrings moved out of sidebar.js and into Scholar.LocalizedStrings
Rudimentary creator adding/editing. lots of things to work on, because it doesn't work.
Added Scholar.CreatorTypes with methods getTypes() (multi-dim array with 'id' and 'name') and getTypeName(creatorTypeID)
Fixed bug in Scholar.Creators.purge() causing SQL error when deleting a non-existent creator
Fixed incorrect field order for itemCreators INSERT queries in save()
Changed setCreator() to take empty creator names (causing DELETE in itemCreators but without shifting up creators below it (or down and above, depending on your perspective) like removeCreators())
The selection no longer lost or moved on folder opening/closing.
The erase functionality works, on Mac (Windows) use the delete (backspace) or forward delete (delete) keys.
unfortunately there are sometimes exceptions so I am not calling erase() on each item until we figure out what the problem is.
view._deleteItem() and view._insertItem() are now view._hideItem() and view._showItem() to better reflect functionality.
Scholar.ItemTypes.getTypes() -- returns associative array of all itemTypes, with 'id' and 'name'
Scholar.ItemTypes.getTypeName(itemTypeID) -- returns pre-l10n type name (e.g. 'book', 'journalArticle')
Removed getLevel()
Updated Object.setPosition() to handle setting the position of new objects without committing, so it can be used within save(). May or may not actually work--my money's on no.
Added Folder.isEmpty()
No Folder.setPosition() yet, but, then, no editing or saving of folders at all--coming soon
Added getLevel() functions to Scholar.Object and Scholar.Folder -- save() and setPosition() not yet updated
Updated sample data to include levels
Added orderIndex (from treeOrder table, now) back into Scholar.Object data
New Scholar.Objects method for treeView: getTreeRows() -- returns mixed array of all Folder and Object objects in the proper order, type testable with instanceof (e.g. if (obj instanceof Scholar.Folder))
Scholar.Objects.get() and getAll() return arrays hashed by objectID again, since they're no longer used directly by treeView
Scholar.Objects.get() now returns the object directly if only one argument and scalar (i.e. one id)
Updated schema and sample data to handle folder ordering
Added include.js for use in non-browser.xul windows to bring in the SCHOLAR_CONFIG and Scholar objects
Adjusted sidebar to use shared object
Added test line (displayable by clicking "Hello, World" before and after sidebar load to demonstrate cross-window access
I also started implementing some of the localization. There is a lot to do still, and I am still learning a lot of the Firefox extension technologies (XUL, adv. Javascript, etc.) but things are going great.
Fixed object retrieval queries to use orderIndex is 0 rather than 1, since that's the default now
Scholar_Objects.getAll() now uses loaded.push() rather than loaded[objectID], since _for (objectID in objects)_ isn't an option with treeview
Scholar_Object.getField() now returns an empty string rather than false for empty values
Added some new core functions:
- Scholar.varDump(), after PHP's var_dump()
- Scholar.flattenArguments(), to flatten mixed array/literal argument lists into a single array
- Scholar.join() -- a version of join() that operates externally, for use on, for example, the arguments object (safer than extending Object)
- Scholar.Hash, a slightly smarter associative array -- not perfect, but brings a proper length property and a few convenience methods (and allows for other additions) -- should probably be limited to places where the length property or other additional additions are needed, since its use is a little non-standard (e.g. you have to remember to do _for (i in arr.items)_ rather than just _for (i in arr)_, to use set(), etc.)
Moved schema file out of chrome and removed XML tags, since it will no longer be accessed by XMLHTTP
Changed schema updater to use XPCOM components rather than XMLHTTP
Converted DB class to a singleton named Scholar_DB
Scholar_DB.query() now returns associative array similar to mysql_fetch_assoc() for SELECT statements rather than a mozIStorageStatementWrapper -- the mozStorage executeDataSet() function doesn't work yet, so we do it this way
Added DB functions:
- beginTransaction(), commitTransaction(), rollbackTransaction()
- columnQuery() -- one column, multiple rows, returned as array indexed by row
- getColumns() and getColumnHash
DB query functions can now handle bind parameters passed as an array of object literals: e.g. [{'int':2},{'string':'foobar'}]
valueQuery() now returns an int for COUNT(*) queries, so the result can be tested without a "0" being true
Changed _initializeSchema to drop existing tables before creating new ones, hacked with try/catch until DROP TABLE IF EXISTS works with the mozStorage extension (it's already in the latest SQLite release)
Added DB_REBUILD config flag to manually trigger schema regeneration
Added debug logging at level 5 for all SQL queries
Updated sample data