?? feed-subscriptions.js
字號:
# -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-# ***** BEGIN LICENSE BLOCK *****# Version: MPL 1.1/GPL 2.0/LGPL 2.1## The contents of this file are subject to the Mozilla Public License Version# 1.1 (the "License"); you may not use this file except in compliance with# the License. You may obtain a copy of the License at# http://www.mozilla.org/MPL/## Software distributed under the License is distributed on an "AS IS" basis,# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License# for the specific language governing rights and limitations under the# License.## The Original Code is Thunderbird RSS Subscription Manager## The Initial Developer of the Original Code is# The Mozilla Foundation.# Portions created by the Initial Developer are Copyright (C) 2005# the Initial Developer. All Rights Reserved.## Contributor(s):# Scott MacGregor <mscott@mozilla.org>## Alternatively, the contents of this file may be used under the terms of# either the GNU General Public License Version 2 or later (the "GPL"), or# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),# in which case the provisions of the GPL or the LGPL are applicable instead# of those above. If you wish to allow use of your version of this file only# under the terms of either the GPL or the LGPL, and not to allow others to# use your version of this file under the terms of the MPL, indicate your# decision by deleting the provisions above and replace them with the notice# and other provisions required by the GPL or the LGPL. If you do not delete# the provisions above, a recipient may use your version of this file under# the terms of any one of the MPL, the GPL or the LGPL.## ***** END LICENSE BLOCK ******const MSG_FOLDER_FLAG_TRASH = 0x0100;const IPS = Components.interfaces.nsIPromptService;const nsIDragService = Components.interfaces.nsIDragService;const kRowIndexUndefined = -1;var gFeedSubscriptionsWindow = { mFeedContainers : [], mTree : null, mBundle : null, mRSSServer : null, init: function () { // extract the server argument if (window.arguments[0].server) this.mRSSServer = window.arguments[0].server; var docshell = window.QueryInterface(Components.interfaces.nsIInterfaceRequestor) .getInterface(Components.interfaces.nsIWebNavigation) .QueryInterface(Components.interfaces.nsIDocShell); docshell.allowAuth = true; this.mTree = document.getElementById("rssSubscriptionsList"); this.mBundle = document.getElementById("bundle_newsblog"); this.loadSubscriptions(); this.mTree.treeBoxObject.view = this.mView; if (this.mView.rowCount > 0) this.mTree.view.selection.select(0); }, uninit: function () { var dismissDialog = true; // if we are in the middle of subscribing to a feed, inform the user that // dismissing the dialog right now will abort the feed subscription. // cheat and look at the disabled state of the add button to determine if we are in the middle of a new subscription if (document.getElementById('addFeed').getAttribute('disabled')) { var promptService = Components.classes["@mozilla.org/embedcomp/prompt-service;1"].getService(IPS); var newsBlogBundle = document.getElementById("bundle_newsblog"); dismissDialog = !(promptService.confirmEx(window, newsBlogBundle.getString('subscribe-cancelSubscriptionTitle'), newsBlogBundle.getString('subscribe-cancelSubscription'), (IPS.BUTTON_TITLE_YES * IPS.BUTTON_POS_0) + (IPS.BUTTON_TITLE_NO * IPS.BUTTON_POS_1), null, null, null, null, { })); } return dismissDialog; }, mView: { mRowCount : 0, get rowCount() { return this.mRowCount; }, getItemAtIndex: function (aIndex) { return gFeedSubscriptionsWindow.mFeedContainers[aIndex]; }, removeItemAtIndex: function (aIndex, aCount) { var itemToRemove = this.getItemAtIndex(aIndex); if (!itemToRemove) return; var parentIndex = this.getParentIndex(aIndex); if (parentIndex != kRowIndexUndefined) { var parent = this.getItemAtIndex(parentIndex); if (parent) { for (var index = 0; index < parent.children.length; index++) if (parent.children[index] == itemToRemove) { parent.children.splice(index, 1); break; } } } // now remove it from our view gFeedSubscriptionsWindow.mFeedContainers.splice(aIndex, 1); // now invalidate the correct tree rows var tbo = gFeedSubscriptionsWindow.mTree.treeBoxObject; this.mRowCount--; tbo.rowCountChanged(aIndex, -1); // now update the selection position if (aIndex < gFeedSubscriptionsWindow.mFeedContainers.length) this.selection.select(aIndex); else this.selection.clearSelection(); // now refocus the tree gFeedSubscriptionsWindow.mTree.focus(); }, getCellText: function (aIndex, aColumn) { var item = this.getItemAtIndex(aIndex); if (!item) return ""; else if (aColumn.id == "folderNameCol") return item.name; }, _selection: null, get selection () { return this._selection; }, set selection (val) { this._selection = val; return val; }, getRowProperties: function (aIndex, aProperties) {}, getCellProperties: function (aIndex, aColumn, aProperties) {}, getColumnProperties: function (aColumn, aProperties) {}, isContainer: function (aIndex) { var item = this.getItemAtIndex(aIndex); return item ? item.container : false; }, isContainerOpen: function (aIndex) { var item = this.getItemAtIndex(aIndex); return item ? item.open : false; }, isContainerEmpty: function (aIndex) { var item = this.getItemAtIndex(aIndex); if (!item) return false; return item.children.length == 0; }, isSeparator: function (aIndex) { return false; }, isSorted: function (aIndex) { return false; }, canDrop: function (aIndex, aOrientation) { var dropResult = this.extractDragData(); return (aOrientation == Components.interfaces.nsITreeView.DROP_ON) && dropResult.canDrop && (dropResult.url || (dropResult.index != kRowIndexUndefined)); }, mDropUrl: "", mDropFolderUrl: "", drop: function (aIndex, aOrientation) { var results = this.extractDragData(); if (!results.canDrop) return; if (results.url) { var folderItem = this.getItemAtIndex(aIndex); // don't freeze the app that initiaed the drop just because we are in a loop waiting for the user // to dimisss the add feed dialog.... this.mDropUrl = results.url; this.mDropFolderUrl = folderItem.url; setTimeout(processDrop, 0); } else if (results.index != kRowIndexUndefined) gFeedSubscriptionsWindow.moveFeed(results.index, aIndex); }, // helper function for drag and drop extractDragData: function() { var canDrop = false; var urlToDrop; var sourceIndex = kRowIndexUndefined; var dragService = Components.classes["@mozilla.org/widget/dragservice;1"].getService().QueryInterface(nsIDragService); var dragSession = dragService.getCurrentSession(); var transfer = Components.classes["@mozilla.org/widget/transferable;1"].createInstance(Components.interfaces.nsITransferable); transfer.addDataFlavor("text/x-moz-url"); transfer.addDataFlavor("text/x-moz-feed-index"); dragSession.getData (transfer, 0); var dataObj = new Object(); var flavor = new Object(); var len = new Object(); try { transfer.getAnyTransferData(flavor, dataObj, len); } catch (ex) { return { canDrop: false, url: "" }; } if (dataObj.value) { dataObj = dataObj.value.QueryInterface(Components.interfaces.nsISupportsString); sourceUri = dataObj.data.substring(0, len.value); // pull the URL out of the data object if (flavor.value == 'text/x-moz-url') { var uri = Components.classes["@mozilla.org/network/standard-url;1"].createInstance(Components.interfaces.nsIURI); uri.spec = sourceUri.split("\n")[0]; if (uri.schemeIs("http") || uri.schemeIs("https")) { urlToDrop = uri.spec; canDrop = true; } } else if (flavor.value == 'text/x-moz-feed-index') { sourceIndex = parseInt(sourceUri); canDrop = true; } } // if dataObj.value return { canDrop: canDrop, url: urlToDrop, index: sourceIndex }; }, getParentIndex: function (aIndex) { var item = this.getItemAtIndex(aIndex); if (item) { for (var index = aIndex; index >= 0; index--) if (gFeedSubscriptionsWindow.mFeedContainers[index].level < item.level) return index; } return kRowIndexUndefined; }, hasNextSibling: function (aParentIndex, aIndex) { var item = this.getItemAtIndex(aIndex); if (item) { // if the next node in the view has the same level as us, then we must have a next sibling... if (aIndex + 1 < gFeedSubscriptionsWindow.mFeedContainers.length ) return this.getItemAtIndex(aIndex + 1).level == item.level; } return false; }, hasPreviousSibling: function (aIndex) { var item = this.getItemAtIndex(aIndex); if (item && aIndex) return this.getItemAtIndex(aIndex - 1).level == item.level; else return false; }, getLevel: function (aIndex) { var item = this.getItemAtIndex(aIndex); if (!item) return 0; return item.level; }, getImageSrc: function (aIndex, aColumn) {}, getProgressMode: function (aIndex, aColumn) {}, getCellValue: function (aIndex, aColumn) {}, setTree: function (aTree) {}, toggleOpenState: function (aIndex) { var item = this.getItemAtIndex(aIndex); if (!item) return; // save off the current selection item var seln = this.selection; var currentSelectionIndex = seln.currentIndex; var multiplier = item.open ? -1 : 1; var delta = multiplier * item.children.length; this.mRowCount += delta; if (multiplier < 0) gFeedSubscriptionsWindow.mFeedContainers.splice(aIndex + 1, item.children.length); else for (var i = 0; i < item.children.length; i++) gFeedSubscriptionsWindow.mFeedContainers.splice(aIndex + 1 + i, 0, item.children[i]); // add or remove the children from our view item.open = !item.open; gFeedSubscriptionsWindow.mTree.treeBoxObject.rowCountChanged(aIndex, delta); // now restore selection seln.select(currentSelectionIndex); }, cycleHeader: function (aColumn) {}, selectionChanged: function () {}, cycleCell: function (aIndex, aColumn) {}, isEditable: function (aIndex, aColumn) { return false; }, setCellValue: function (aIndex, aColumn, aValue) {}, setCellText: function (aIndex, aColumn, aValue) {}, performAction: function (aAction) {}, performActionOnRow: function (aAction, aIndex) {}, performActionOnCell: function (aAction, aindex, aColumn) {} }, makeFolderObject: function (aFolder, aCurrentLevel) { var folderObject = { children : [], name : aFolder.prettiestName, level : aCurrentLevel, url : aFolder.QueryInterface(Components.interfaces.nsIRDFResource).Value, open : false, container: true }; // if a feed has any sub folders, we should add them to the list of children if (aFolder.hasSubFolders) { var folderEnumerator = aFolder.GetSubFolders(); var done = false;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -