diff options
author | Thomas Groman <tgroman@nuegia.net> | 2020-04-20 20:49:37 -0700 |
---|---|---|
committer | Thomas Groman <tgroman@nuegia.net> | 2020-04-20 20:49:37 -0700 |
commit | f9cab004186edb425a9b88ad649726605080a17c (patch) | |
tree | e2dae51d3144e83d097a12e7a1499e3ea93f90be /base/content/sanitizeDialog.js | |
parent | f428692de8b59ab89a66502c079e1823dfda8aeb (diff) | |
download | webbrowser-f9cab004186edb425a9b88ad649726605080a17c.tar webbrowser-f9cab004186edb425a9b88ad649726605080a17c.tar.gz webbrowser-f9cab004186edb425a9b88ad649726605080a17c.tar.lz webbrowser-f9cab004186edb425a9b88ad649726605080a17c.tar.xz webbrowser-f9cab004186edb425a9b88ad649726605080a17c.zip |
move browser to webbrowser/
Diffstat (limited to 'base/content/sanitizeDialog.js')
-rw-r--r-- | base/content/sanitizeDialog.js | 910 |
1 files changed, 0 insertions, 910 deletions
diff --git a/base/content/sanitizeDialog.js b/base/content/sanitizeDialog.js deleted file mode 100644 index 7861132..0000000 --- a/base/content/sanitizeDialog.js +++ /dev/null @@ -1,910 +0,0 @@ -/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -var Cc = Components.classes; -var Ci = Components.interfaces; - -var gSanitizePromptDialog = { - - get bundleBrowser() - { - if (!this._bundleBrowser) - this._bundleBrowser = document.getElementById("bundleBrowser"); - return this._bundleBrowser; - }, - - get selectedTimespan() - { - var durList = document.getElementById("sanitizeDurationChoice"); - return parseInt(durList.value); - }, - - get sanitizePreferences() - { - if (!this._sanitizePreferences) { - this._sanitizePreferences = - document.getElementById("sanitizePreferences"); - } - return this._sanitizePreferences; - }, - - get warningBox() - { - return document.getElementById("sanitizeEverythingWarningBox"); - }, - - init: function () - { - // This is used by selectByTimespan() to determine if the window has loaded. - this._inited = true; - - var s = new Sanitizer(); - s.prefDomain = "privacy.cpd."; - - let sanitizeItemList = document.querySelectorAll("#itemList > [preference]"); - for (let i = 0; i < sanitizeItemList.length; i++) { - let prefItem = sanitizeItemList[i]; - let name = s.getNameFromPreference(prefItem.getAttribute("preference")); - s.canClearItem(name, function canClearCallback(aItem, aCanClear, aPrefItem) { - if (!aCanClear) { - aPrefItem.preference = null; - aPrefItem.checked = false; - aPrefItem.disabled = true; - } - }, prefItem); - } - - document.documentElement.getButton("accept").label = - this.bundleBrowser.getString("sanitizeButtonOK"); - - if (this.selectedTimespan === Sanitizer.TIMESPAN_EVERYTHING) { - this.prepareWarning(); - this.warningBox.hidden = false; - document.title = - this.bundleBrowser.getString("sanitizeDialog2.everything.title"); - } - else - this.warningBox.hidden = true; - }, - - selectByTimespan: function () - { - // This method is the onselect handler for the duration dropdown. As a - // result it's called a couple of times before onload calls init(). - if (!this._inited) - return; - - var warningBox = this.warningBox; - - // If clearing everything - if (this.selectedTimespan === Sanitizer.TIMESPAN_EVERYTHING) { - this.prepareWarning(); - if (warningBox.hidden) { - warningBox.hidden = false; - window.resizeBy(0, warningBox.boxObject.height); - } - window.document.title = - this.bundleBrowser.getString("sanitizeDialog2.everything.title"); - return; - } - - // If clearing a specific time range - if (!warningBox.hidden) { - window.resizeBy(0, -warningBox.boxObject.height); - warningBox.hidden = true; - } - window.document.title = - window.document.documentElement.getAttribute("noneverythingtitle"); - }, - - sanitize: function () - { - // Update pref values before handing off to the sanitizer (bug 453440) - this.updatePrefs(); - var s = new Sanitizer(); - s.prefDomain = "privacy.cpd."; - - s.range = Sanitizer.getClearRange(this.selectedTimespan); - s.ignoreTimespan = !s.range; - - // As the sanitize is async, we disable the buttons, update the label on - // the 'accept' button to indicate things are happening and return false - - // once the async operation completes (either with or without errors) - // we close the window. - let docElt = document.documentElement; - let acceptButton = docElt.getButton("accept"); - acceptButton.disabled = true; - acceptButton.setAttribute("label", - this.bundleBrowser.getString("sanitizeButtonClearing")); - docElt.getButton("cancel").disabled = true; - try { - s.sanitize().then(window.close, window.close); - } catch (er) { - Components.utils.reportError("Exception during sanitize: " + er); - return true; // We *do* want to close immediately on error. - } - return false; - }, - - /** - * If the panel that displays a warning when the duration is "Everything" is - * not set up, sets it up. Otherwise does nothing. - * - * @param aDontShowItemList Whether only the warning message should be updated. - * True means the item list visibility status should not - * be changed. - */ - prepareWarning: function (aDontShowItemList) { - // If the date and time-aware locale warning string is ever used again, - // initialize it here. Currently we use the no-visits warning string, - // which does not include date and time. See bug 480169 comment 48. - - var warningStringID; - if (this.hasNonSelectedItems()) { - warningStringID = "sanitizeSelectedWarning"; - if (!aDontShowItemList) - this.showItemList(); - } - else { - warningStringID = "sanitizeEverythingWarning2"; - } - - var warningDesc = document.getElementById("sanitizeEverythingWarning"); - warningDesc.textContent = - this.bundleBrowser.getString(warningStringID); - }, - - /** - * Called when the value of a preference element is synced from the actual - * pref. Enables or disables the OK button appropriately. - */ - onReadGeneric: function () - { - var found = false; - - // Find any other pref that's checked and enabled. - var i = 0; - while (!found && i < this.sanitizePreferences.childNodes.length) { - var preference = this.sanitizePreferences.childNodes[i]; - - found = !!preference.value && - !preference.disabled; - i++; - } - - try { - document.documentElement.getButton("accept").disabled = !found; - } - catch (e) { } - - // Update the warning prompt if needed - this.prepareWarning(true); - - return undefined; - }, - - /** - * Sanitizer.prototype.sanitize() requires the prefs to be up-to-date. - * Because the type of this prefwindow is "child" -- and that's needed because - * without it the dialog has no OK and Cancel buttons -- the prefs are not - * updated on dialogaccept on platforms that don't support instant-apply - * (i.e., Windows). We must therefore manually set the prefs from their - * corresponding preference elements. - */ - updatePrefs : function () - { - var tsPref = document.getElementById("privacy.sanitize.timeSpan"); - Sanitizer.prefs.setIntPref("timeSpan", this.selectedTimespan); - - // Keep the pref for the download history in sync with the history pref. - document.getElementById("privacy.cpd.downloads").value = - document.getElementById("privacy.cpd.history").value; - - // Now manually set the prefs from their corresponding preference - // elements. - var prefs = this.sanitizePreferences.rootBranch; - for (let i = 0; i < this.sanitizePreferences.childNodes.length; ++i) { - var p = this.sanitizePreferences.childNodes[i]; - prefs.setBoolPref(p.name, p.value); - } - }, - - /** - * Check if all of the history items have been selected like the default status. - */ - hasNonSelectedItems: function () { - let checkboxes = document.querySelectorAll("#itemList > [preference]"); - for (let i = 0; i < checkboxes.length; ++i) { - let pref = document.getElementById(checkboxes[i].getAttribute("preference")); - if (!pref.value) - return true; - } - return false; - }, - - /** - * Show the history items list. - */ - showItemList: function () { - var itemList = document.getElementById("itemList"); - var expanderButton = document.getElementById("detailsExpander"); - - if (itemList.collapsed) { - expanderButton.className = "expander-up"; - itemList.setAttribute("collapsed", "false"); - if (document.documentElement.boxObject.height) - window.resizeBy(0, itemList.boxObject.height); - } - }, - - /** - * Hide the history items list. - */ - hideItemList: function () { - var itemList = document.getElementById("itemList"); - var expanderButton = document.getElementById("detailsExpander"); - - if (!itemList.collapsed) { - expanderButton.className = "expander-down"; - window.resizeBy(0, -itemList.boxObject.height); - itemList.setAttribute("collapsed", "true"); - } - }, - - /** - * Called by the item list expander button to toggle the list's visibility. - */ - toggleItemList: function () - { - var itemList = document.getElementById("itemList"); - - if (itemList.collapsed) - this.showItemList(); - else - this.hideItemList(); - } - -#ifdef CRH_DIALOG_TREE_VIEW - // A duration value; used in the same context as Sanitizer.TIMESPAN_HOUR, - // Sanitizer.TIMESPAN_2HOURS, et al. This should match the value attribute - // of the sanitizeDurationCustom menuitem. - get TIMESPAN_CUSTOM() - { - return -1; - }, - - get placesTree() - { - if (!this._placesTree) - this._placesTree = document.getElementById("placesTree"); - return this._placesTree; - }, - - init: function () - { - // This is used by selectByTimespan() to determine if the window has loaded. - this._inited = true; - - var s = new Sanitizer(); - s.prefDomain = "privacy.cpd."; - - let sanitizeItemList = document.querySelectorAll("#itemList > [preference]"); - for (let i = 0; i < sanitizeItemList.length; i++) { - let prefItem = sanitizeItemList[i]; - let name = s.getNameFromPreference(prefItem.getAttribute("preference")); - s.canClearItem(name, function canClearCallback(aCanClear) { - if (!aCanClear) { - prefItem.preference = null; - prefItem.checked = false; - prefItem.disabled = true; - } - }); - } - - document.documentElement.getButton("accept").label = - this.bundleBrowser.getString("sanitizeButtonOK"); - - this.selectByTimespan(); - }, - - /** - * Sets up the hashes this.durationValsToRows, which maps duration values - * to rows in the tree, this.durationRowsToVals, which maps rows in - * the tree to duration values, and this.durationStartTimes, which maps - * duration values to their corresponding start times. - */ - initDurationDropdown: function () - { - // First, calculate the start times for each duration. - this.durationStartTimes = {}; - var durVals = []; - var durPopup = document.getElementById("sanitizeDurationPopup"); - var durMenuitems = durPopup.childNodes; - for (let i = 0; i < durMenuitems.length; i++) { - let durMenuitem = durMenuitems[i]; - let durVal = parseInt(durMenuitem.value); - if (durMenuitem.localName === "menuitem" && - durVal !== Sanitizer.TIMESPAN_EVERYTHING && - durVal !== this.TIMESPAN_CUSTOM) { - durVals.push(durVal); - let durTimes = Sanitizer.getClearRange(durVal); - this.durationStartTimes[durVal] = durTimes[0]; - } - } - - // Sort the duration values ascending. Because one tree index can map to - // more than one duration, this ensures that this.durationRowsToVals maps - // a row index to the largest duration possible in the code below. - durVals.sort(); - - // Now calculate the rows in the tree of the durations' start times. For - // each duration, we are looking for the node in the tree whose time is the - // smallest time greater than or equal to the duration's start time. - this.durationRowsToVals = {}; - this.durationValsToRows = {}; - var view = this.placesTree.view; - // For all rows in the tree except the grippy row... - for (let i = 0; i < view.rowCount - 1; i++) { - let unfoundDurVals = []; - let nodeTime = view.QueryInterface(Ci.nsINavHistoryResultTreeViewer). - nodeForTreeIndex(i).time; - // For all durations whose rows have not yet been found in the tree, see - // if index i is their index. An index may map to more than one duration, - // in which case the final duration (the largest) wins. - for (let j = 0; j < durVals.length; j++) { - let durVal = durVals[j]; - let durStartTime = this.durationStartTimes[durVal]; - if (nodeTime < durStartTime) { - this.durationValsToRows[durVal] = i - 1; - this.durationRowsToVals[i - 1] = durVal; - } - else - unfoundDurVals.push(durVal); - } - durVals = unfoundDurVals; - } - - // If any durations were not found above, then every node in the tree has a - // time greater than or equal to the duration. In other words, those - // durations include the entire tree (except the grippy row). - for (let i = 0; i < durVals.length; i++) { - let durVal = durVals[i]; - this.durationValsToRows[durVal] = view.rowCount - 2; - this.durationRowsToVals[view.rowCount - 2] = durVal; - } - }, - - /** - * If the Places tree is not set up, sets it up. Otherwise does nothing. - */ - ensurePlacesTreeIsInited: function () - { - if (this._placesTreeIsInited) - return; - - this._placesTreeIsInited = true; - - // Either "Last Four Hours" or "Today" will have the most history. If - // it's been more than 4 hours since today began, "Today" will. Otherwise - // "Last Four Hours" will. - var times = Sanitizer.getClearRange(Sanitizer.TIMESPAN_TODAY); - - // If it's been less than 4 hours since today began, use the past 4 hours. - if (times[1] - times[0] < 14400000000) { // 4*60*60*1000000 - times = Sanitizer.getClearRange(Sanitizer.TIMESPAN_4HOURS); - } - - var histServ = Cc["@mozilla.org/browser/nav-history-service;1"]. - getService(Ci.nsINavHistoryService); - var query = histServ.getNewQuery(); - query.beginTimeReference = query.TIME_RELATIVE_EPOCH; - query.beginTime = times[0]; - query.endTimeReference = query.TIME_RELATIVE_EPOCH; - query.endTime = times[1]; - var opts = histServ.getNewQueryOptions(); - opts.sortingMode = opts.SORT_BY_DATE_DESCENDING; - opts.queryType = opts.QUERY_TYPE_HISTORY; - var result = histServ.executeQuery(query, opts); - - var view = gContiguousSelectionTreeHelper.setTree(this.placesTree, - new PlacesTreeView()); - result.addObserver(view, false); - this.initDurationDropdown(); - }, - - /** - * Called on select of the duration dropdown and when grippyMoved() sets a - * duration based on the location of the grippy row. Selects all the nodes in - * the tree that are contained in the selected duration. If clearing - * everything, the warning panel is shown instead. - */ - selectByTimespan: function () - { - // This method is the onselect handler for the duration dropdown. As a - // result it's called a couple of times before onload calls init(). - if (!this._inited) - return; - - var durDeck = document.getElementById("durationDeck"); - var durList = document.getElementById("sanitizeDurationChoice"); - var durVal = parseInt(durList.value); - var durCustom = document.getElementById("sanitizeDurationCustom"); - - // If grippy row is not at a duration boundary, show the custom menuitem; - // otherwise, hide it. Since the user cannot specify a custom duration by - // using the dropdown, this conditional is true only when this method is - // called onselect from grippyMoved(), so no selection need be made. - if (durVal === this.TIMESPAN_CUSTOM) { - durCustom.hidden = false; - return; - } - durCustom.hidden = true; - - // If clearing everything, show the warning and change the dialog's title. - if (durVal === Sanitizer.TIMESPAN_EVERYTHING) { - this.prepareWarning(); - durDeck.selectedIndex = 1; - window.document.title = - this.bundleBrowser.getString("sanitizeDialog2.everything.title"); - document.documentElement.getButton("accept").disabled = false; - return; - } - - // Otherwise -- if clearing a specific time range -- select that time range - // in the tree. - this.ensurePlacesTreeIsInited(); - durDeck.selectedIndex = 0; - window.document.title = - window.document.documentElement.getAttribute("noneverythingtitle"); - var durRow = this.durationValsToRows[durVal]; - gContiguousSelectionTreeHelper.rangedSelect(durRow); - gContiguousSelectionTreeHelper.scrollToGrippy(); - - // If duration is empty (there are no selected rows), disable the dialog's - // OK button. - document.documentElement.getButton("accept").disabled = durRow < 0; - }, - - sanitize: function () - { - // Update pref values before handing off to the sanitizer (bug 453440) - this.updatePrefs(); - var s = new Sanitizer(); - s.prefDomain = "privacy.cpd."; - - var durList = document.getElementById("sanitizeDurationChoice"); - var durValue = parseInt(durList.value); - s.ignoreTimespan = durValue === Sanitizer.TIMESPAN_EVERYTHING; - - // Set the sanitizer's time range if we're not clearing everything. - if (!s.ignoreTimespan) { - // If user selected a custom timespan, use that. - if (durValue === this.TIMESPAN_CUSTOM) { - var view = this.placesTree.view; - var now = Date.now() * 1000; - // We disable the dialog's OK button if there's no selection, but we'll - // handle that case just in... case. - if (view.selection.getRangeCount() === 0) - s.range = [now, now]; - else { - var startIndexRef = {}; - // Tree sorted by visit date DEscending, so start time time comes last. - view.selection.getRangeAt(0, {}, startIndexRef); - view.QueryInterface(Ci.nsINavHistoryResultTreeViewer); - var startNode = view.nodeForTreeIndex(startIndexRef.value); - s.range = [startNode.time, now]; - } - } - // Otherwise use the predetermined range. - else - s.range = [this.durationStartTimes[durValue], Date.now() * 1000]; - } - - try { - s.sanitize(); - } catch (er) { - Components.utils.reportError("Exception during sanitize: " + er); - } - return true; - }, - - /** - * In order to mark the custom Places tree view and its nsINavHistoryResult - * for garbage collection, we need to break the reference cycle between the - * two. - */ - unload: function () - { - let result = this.placesTree.getResult(); - result.removeObserver(this.placesTree.view); - this.placesTree.view = null; - }, - - /** - * Called when the user moves the grippy by dragging it, clicking in the tree, - * or on keypress. Updates the duration dropdown so that it displays the - * appropriate specific or custom duration. - * - * @param aEventName - * The name of the event whose handler called this method, e.g., - * "ondragstart", "onkeypress", etc. - * @param aEvent - * The event captured in the event handler. - */ - grippyMoved: function (aEventName, aEvent) - { - gContiguousSelectionTreeHelper[aEventName](aEvent); - var lastSelRow = gContiguousSelectionTreeHelper.getGrippyRow() - 1; - var durList = document.getElementById("sanitizeDurationChoice"); - var durValue = parseInt(durList.value); - - // Multiple durations can map to the same row. Don't update the dropdown - // if the current duration is valid for lastSelRow. - if ((durValue !== this.TIMESPAN_CUSTOM || - lastSelRow in this.durationRowsToVals) && - (durValue === this.TIMESPAN_CUSTOM || - this.durationValsToRows[durValue] !== lastSelRow)) { - // Setting durList.value causes its onselect handler to fire, which calls - // selectByTimespan(). - if (lastSelRow in this.durationRowsToVals) - durList.value = this.durationRowsToVals[lastSelRow]; - else - durList.value = this.TIMESPAN_CUSTOM; - } - - // If there are no selected rows, disable the dialog's OK button. - document.documentElement.getButton("accept").disabled = lastSelRow < 0; - } -#endif - -}; - - -#ifdef CRH_DIALOG_TREE_VIEW -/** - * A helper for handling contiguous selection in the tree. - */ -var gContiguousSelectionTreeHelper = { - - /** - * Gets the tree associated with this helper. - */ - get tree() - { - return this._tree; - }, - - /** - * Sets the tree that this module handles. The tree is assigned a new view - * that is equipped to handle contiguous selection. You can pass in an - * object that will be used as the prototype of the new view. Otherwise - * the tree's current view is used as the prototype. - * - * @param aTreeElement - * The tree element - * @param aProtoTreeView - * If defined, this will be used as the prototype of the tree's new - * view - * @return The new view - */ - setTree: function CSTH_setTree(aTreeElement, aProtoTreeView) - { - this._tree = aTreeElement; - var newView = this._makeTreeView(aProtoTreeView || aTreeElement.view); - aTreeElement.view = newView; - return newView; - }, - - /** - * The index of the row that the grippy occupies. Note that the index of the - * last selected row is getGrippyRow() - 1. If getGrippyRow() is 0, then - * no selection exists. - * - * @return The row index of the grippy - */ - getGrippyRow: function CSTH_getGrippyRow() - { - var sel = this.tree.view.selection; - var rangeCount = sel.getRangeCount(); - if (rangeCount === 0) - return 0; - if (rangeCount !== 1) { - throw "contiguous selection tree helper: getGrippyRow called with " + - "multiple selection ranges"; - } - var max = {}; - sel.getRangeAt(0, {}, max); - return max.value + 1; - }, - - /** - * Helper function for the dragover event. Your dragover listener should - * call this. It updates the selection in the tree under the mouse. - * - * @param aEvent - * The observed dragover event - */ - ondragover: function CSTH_ondragover(aEvent) - { - // Without this when dragging on Windows the mouse cursor is a "no" sign. - // This makes it a drop symbol. - var ds = Cc["@mozilla.org/widget/dragservice;1"]. - getService(Ci.nsIDragService). - getCurrentSession(); - ds.canDrop = true; - ds.dragAction = 0; - - var tbo = this.tree.treeBoxObject; - aEvent.QueryInterface(Ci.nsIDOMMouseEvent); - var hoverRow = tbo.getRowAt(aEvent.clientX, aEvent.clientY); - - if (hoverRow < 0) - return; - - this.rangedSelect(hoverRow - 1); - }, - - /** - * Helper function for the dragstart event. Your dragstart listener should - * call this. It starts a drag session. - * - * @param aEvent - * The observed dragstart event - */ - ondragstart: function CSTH_ondragstart(aEvent) - { - var tbo = this.tree.treeBoxObject; - var clickedRow = tbo.getRowAt(aEvent.clientX, aEvent.clientY); - - if (clickedRow !== this.getGrippyRow()) - return; - - // This part is a hack. What we really want is a grab and slide, not - // drag and drop. Start a move drag session with dummy data and a - // dummy region. Set the region's coordinates to (Infinity, Infinity) - // so it's drawn offscreen and its size to (1, 1). - var arr = Cc["@mozilla.org/supports-array;1"]. - createInstance(Ci.nsISupportsArray); - var trans = Cc["@mozilla.org/widget/transferable;1"]. - createInstance(Ci.nsITransferable); - trans.init(null); - trans.setTransferData('dummy-flavor', null, 0); - arr.AppendElement(trans); - var reg = Cc["@mozilla.org/gfx/region;1"]. - createInstance(Ci.nsIScriptableRegion); - reg.setToRect(Infinity, Infinity, 1, 1); - var ds = Cc["@mozilla.org/widget/dragservice;1"]. - getService(Ci.nsIDragService); - ds.invokeDragSession(aEvent.target, arr, reg, ds.DRAGDROP_ACTION_MOVE); - }, - - /** - * Helper function for the keypress event. Your keypress listener should - * call this. Users can use Up, Down, Page Up/Down, Home, and End to move - * the bottom of the selection window. - * - * @param aEvent - * The observed keypress event - */ - onkeypress: function CSTH_onkeypress(aEvent) - { - var grippyRow = this.getGrippyRow(); - var tbo = this.tree.treeBoxObject; - var rangeEnd; - switch (aEvent.keyCode) { - case aEvent.DOM_VK_HOME: - rangeEnd = 0; - break; - case aEvent.DOM_VK_PAGE_UP: - rangeEnd = grippyRow - tbo.getPageLength(); - break; - case aEvent.DOM_VK_UP: - rangeEnd = grippyRow - 2; - break; - case aEvent.DOM_VK_DOWN: - rangeEnd = grippyRow; - break; - case aEvent.DOM_VK_PAGE_DOWN: - rangeEnd = grippyRow + tbo.getPageLength(); - break; - case aEvent.DOM_VK_END: - rangeEnd = this.tree.view.rowCount - 2; - break; - default: - return; - break; - } - - aEvent.stopPropagation(); - - // First, clip rangeEnd. this.rangedSelect() doesn't clip the range if we - // select past the ends of the tree. - if (rangeEnd < 0) - rangeEnd = -1; - else if (this.tree.view.rowCount - 2 < rangeEnd) - rangeEnd = this.tree.view.rowCount - 2; - - // Next, (de)select. - this.rangedSelect(rangeEnd); - - // Finally, scroll the tree. We always want one row above and below the - // grippy row to be visible if possible. - if (rangeEnd < grippyRow) // moved up - tbo.ensureRowIsVisible(rangeEnd < 0 ? 0 : rangeEnd); - else { // moved down - if (rangeEnd + 2 < this.tree.view.rowCount) - tbo.ensureRowIsVisible(rangeEnd + 2); - else if (rangeEnd + 1 < this.tree.view.rowCount) - tbo.ensureRowIsVisible(rangeEnd + 1); - } - }, - - /** - * Helper function for the mousedown event. Your mousedown listener should - * call this. Users can click on individual rows to make the selection - * jump to them immediately. - * - * @param aEvent - * The observed mousedown event - */ - onmousedown: function CSTH_onmousedown(aEvent) - { - var tbo = this.tree.treeBoxObject; - var clickedRow = tbo.getRowAt(aEvent.clientX, aEvent.clientY); - - if (clickedRow < 0 || clickedRow >= this.tree.view.rowCount) - return; - - if (clickedRow < this.getGrippyRow()) - this.rangedSelect(clickedRow); - else if (clickedRow > this.getGrippyRow()) - this.rangedSelect(clickedRow - 1); - }, - - /** - * Selects range [0, aEndRow] in the tree. The grippy row will then be at - * index aEndRow + 1. aEndRow may be -1, in which case the selection is - * cleared and the grippy row will be at index 0. - * - * @param aEndRow - * The range [0, aEndRow] will be selected. - */ - rangedSelect: function CSTH_rangedSelect(aEndRow) - { - var tbo = this.tree.treeBoxObject; - if (aEndRow < 0) - this.tree.view.selection.clearSelection(); - else - this.tree.view.selection.rangedSelect(0, aEndRow, false); - tbo.invalidateRange(tbo.getFirstVisibleRow(), tbo.getLastVisibleRow()); - }, - - /** - * Scrolls the tree so that the grippy row is in the center of the view. - */ - scrollToGrippy: function CSTH_scrollToGrippy() - { - var rowCount = this.tree.view.rowCount; - var tbo = this.tree.treeBoxObject; - var pageLen = tbo.getPageLength() || - parseInt(this.tree.getAttribute("rows")) || - 10; - - // All rows fit on a single page. - if (rowCount <= pageLen) - return; - - var scrollToRow = this.getGrippyRow() - Math.ceil(pageLen / 2.0); - - // Grippy row is in first half of first page. - if (scrollToRow < 0) - scrollToRow = 0; - - // Grippy row is in last half of last page. - else if (rowCount < scrollToRow + pageLen) - scrollToRow = rowCount - pageLen; - - tbo.scrollToRow(scrollToRow); - }, - - /** - * Creates a new tree view suitable for contiguous selection. If - * aProtoTreeView is specified, it's used as the new view's prototype. - * Otherwise the tree's current view is used as the prototype. - * - * @param aProtoTreeView - * Used as the new view's prototype if specified - */ - _makeTreeView: function CSTH__makeTreeView(aProtoTreeView) - { - var view = aProtoTreeView; - var that = this; - - //XXXadw: When Alex gets the grippy icon done, this may or may not change, - // depending on how we style it. - view.isSeparator = function CSTH_View_isSeparator(aRow) - { - return aRow === that.getGrippyRow(); - }; - - // rowCount includes the grippy row. - view.__defineGetter__("_rowCount", view.__lookupGetter__("rowCount")); - view.__defineGetter__("rowCount", - function CSTH_View_rowCount() - { - return this._rowCount + 1; - }); - - // This has to do with visual feedback in the view itself, e.g., drawing - // a small line underneath the dropzone. Not what we want. - view.canDrop = function CSTH_View_canDrop() { return false; }; - - // No clicking headers to sort the tree or sort feedback on columns. - view.cycleHeader = function CSTH_View_cycleHeader() {}; - view.sortingChanged = function CSTH_View_sortingChanged() {}; - - // Override a bunch of methods to account for the grippy row. - - view._getCellProperties = view.getCellProperties; - view.getCellProperties = - function CSTH_View_getCellProperties(aRow, aCol) - { - var grippyRow = that.getGrippyRow(); - if (aRow === grippyRow) - return "grippyRow"; - if (aRow < grippyRow) - return this._getCellProperties(aRow, aCol); - - return this._getCellProperties(aRow - 1, aCol); - }; - - view._getRowProperties = view.getRowProperties; - view.getRowProperties = - function CSTH_View_getRowProperties(aRow) - { - var grippyRow = that.getGrippyRow(); - if (aRow === grippyRow) - return "grippyRow"; - - if (aRow < grippyRow) - return this._getRowProperties(aRow); - - return this._getRowProperties(aRow - 1); - }; - - view._getCellText = view.getCellText; - view.getCellText = - function CSTH_View_getCellText(aRow, aCol) - { - var grippyRow = that.getGrippyRow(); - if (aRow === grippyRow) - return ""; - aRow = aRow < grippyRow ? aRow : aRow - 1; - return this._getCellText(aRow, aCol); - }; - - view._getImageSrc = view.getImageSrc; - view.getImageSrc = - function CSTH_View_getImageSrc(aRow, aCol) - { - var grippyRow = that.getGrippyRow(); - if (aRow === grippyRow) - return ""; - aRow = aRow < grippyRow ? aRow : aRow - 1; - return this._getImageSrc(aRow, aCol); - }; - - view.isContainer = function CSTH_View_isContainer(aRow) { return false; }; - view.getParentIndex = function CSTH_View_getParentIndex(aRow) { return -1; }; - view.getLevel = function CSTH_View_getLevel(aRow) { return 0; }; - view.hasNextSibling = function CSTH_View_hasNextSibling(aRow, aAfterIndex) - { - return aRow < this.rowCount - 1; - }; - - return view; - } -}; -#endif |