1 # -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2 # ***** BEGIN LICENSE BLOCK *****
3 # Version: MPL 1.1/GPL 2.0/LGPL 2.1
5 # The contents of this file are subject to the Mozilla Public License Version
6 # 1.1 (the "License"); you may not use this file except in compliance with
7 # the License. You may obtain a copy of the License at
8 # http://www.mozilla.org/MPL/
10 # Software distributed under the License is distributed on an "AS IS" basis,
11 # WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 # for the specific language governing rights and limitations under the
15 # The Original Code is the Firefox Preferences System.
17 # The Initial Developer of the Original Code is
19 # Portions created by the Initial Developer are Copyright (C) 2005
20 # the Initial Developer. All Rights Reserved.
23 # Ben Goodger <ben@mozilla.org>
24 # Ehsan Akhgari <ehsan.akhgari@gmail.com>
26 # Alternatively, the contents of this file may be used under the terms of
27 # either the GNU General Public License Version 2 or later (the "GPL"), or
28 # the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
29 # in which case the provisions of the GPL or the LGPL are applicable instead
30 # of those above. If you wish to allow use of your version of this file only
31 # under the terms of either the GPL or the LGPL, and not to allow others to
32 # use your version of this file under the terms of the MPL, indicate your
33 # decision by deleting the provisions above and replace them with the notice
34 # and other provisions required by the GPL or the LGPL. If you do not delete
35 # the provisions above, a recipient may use your version of this file under
36 # the terms of any one of the MPL, the GPL or the LGPL.
38 # ***** END LICENSE BLOCK *****
43 _cm : Components.classes[
"@mozilla.org/cookiemanager;1"]
44 .getService(Components.interfaces.nsICookieManager),
45 _ds : Components.classes[
"@mozilla.org/intl/scriptabledateformat;1"]
46 .getService(Components.interfaces.nsIScriptableDateFormat),
53 var
os = Components.classes[
"@mozilla.org/observer-service;1"]
54 .getService(Components.interfaces.nsIObserverService);
55 os.addObserver(
this,
"cookie-changed",
false);
56 os.addObserver(
this,
"perm-changed",
false);
58 this._bundle = document.getElementById(
"bundlePreferences");
59 this._tree = document.getElementById(
"cookiesList");
61 this._populateList(
true);
63 document.getElementById(
"filter").focus();
67 var
os = Components.classes[
"@mozilla.org/observer-service;1"]
68 .getService(Components.interfaces.nsIObserverService);
69 os.removeObserver(
this,
"cookie-changed");
70 os.removeObserver(
this,
"perm-changed");
73 _populateList:
function (aInitialLoad) {
75 this._tree.treeBoxObject.view = this._view;
78 if (this._view.rowCount > 0)
79 this._tree.view.selection.select(0);
82 if (
"arguments" in
window &&
84 window.arguments[0].filterString)
85 this.setFilter(
window.arguments[0].filterString);
88 if (document.getElementById(
"filter").value !=
"")
95 _cookieEquals:
function (aCookieA, aCookieB, aStrippedHost) {
96 return aCookieA.rawHost == aStrippedHost &&
97 aCookieA.name == aCookieB.name &&
98 aCookieA.path == aCookieB.path;
102 if (aTopic !=
"cookie-changed")
105 if (
aCookie instanceof Components.interfaces.nsICookie) {
106 var strippedHost = this._makeStrippedHost(
aCookie.host);
107 if (
aData ==
"changed")
108 this._handleCookieChanged(
aCookie, strippedHost);
109 else if (
aData ==
"added")
110 this._handleCookieAdded(
aCookie, strippedHost);
112 else if (
aData ==
"cleared") {
114 this._hostOrder = [];
116 var oldRowCount = this._view._rowCount;
117 this._view._rowCount = 0;
118 this._tree.treeBoxObject.rowCountChanged(0, -oldRowCount);
119 this._view.selection.clearSelection();
121 else if (
aData ==
"reload") {
126 this._populateList(
false);
133 _handleCookieChanged:
function (changedCookie, strippedHost) {
135 var cookieItem =
null;
136 if (!this._view._filtered) {
137 for (var
i = 0;
i < this._hostOrder.length; ++
i) {
139 var hostItem = this._hosts[this._hostOrder[
i]];
140 if (this._hostOrder[
i] == strippedHost) {
143 for (var j = 0; j < hostItem.cookies.length; ++j) {
145 var currCookie = hostItem.cookies[j];
146 if (this._cookieEquals(currCookie, changedCookie, strippedHost)) {
147 currCookie.value = changedCookie.value;
148 currCookie.isSecure = changedCookie.isSecure;
149 currCookie.isDomain = changedCookie.isDomain;
150 currCookie.expires = changedCookie.expires;
151 cookieItem = currCookie;
156 else if (hostItem.open)
157 rowIndex += hostItem.cookies.length;
164 for (rowIndex = 0; rowIndex < this._view._filterSet.length; ++rowIndex) {
165 currCookie = this._view._filterSet[rowIndex];
166 if (this._cookieEquals(currCookie, changedCookie, strippedHost)) {
167 currCookie.value = changedCookie.value;
168 currCookie.isSecure = changedCookie.isSecure;
169 currCookie.isDomain = changedCookie.isDomain;
170 currCookie.expires = changedCookie.expires;
171 cookieItem = currCookie;
178 this._tree.treeBoxObject.invalidateRow(rowIndex);
180 if (cookieItem !=
null && this._view.selection.currentIndex == rowIndex)
181 this._updateCookieData(cookieItem);
184 _handleCookieAdded:
function (changedCookie, strippedHost) {
185 var rowCountImpact = 0;
186 var addedHost = {
value: 0 };
187 this._addCookie(strippedHost, changedCookie, addedHost);
188 if (!this._view._filtered) {
192 if (addedHost.value ||
this._hosts[strippedHost].open)
198 var c = this._makeCookieObject(strippedHost, changedCookie);
199 if (this._cookieMatchesFilter(c)) {
200 this._view._filterSet.push(this._makeCookieObject(strippedHost, changedCookie));
206 var oldRowCount = this._rowCount;
207 this._view._rowCount += rowCountImpact;
208 this._tree.treeBoxObject.rowCountChanged(oldRowCount - 1, rowCountImpact);
210 document.getElementById(
"removeAllCookies").disabled = this._view._filtered;
221 return this._rowCount;
224 _getItemAtIndex:
function (aIndex) {
226 return this._filterSet[aIndex];
229 var
count = 0, hostIndex = 0;
231 var cacheIndex = Math.min(this._cacheValid, aIndex);
232 if (cacheIndex > 0) {
233 var cacheItem = this._cacheItems[cacheIndex];
234 start = cacheItem[
'start'];
235 count = hostIndex = cacheItem[
'count'];
240 if (!currHost)
continue;
245 var cacheEntry = {
'start' :
i,
'count' : count };
246 var cacheStart =
count;
249 if (count < aIndex && aIndex <= (count + currHost.cookies.length)) {
253 for (var
i = 0;
i < currHost.cookies.length; ++
i) {
254 if (count == aIndex) {
255 var cookie = currHost.cookies[
i];
256 cookie.parentIndex = hostIndex;
267 count += currHost.cookies.length + 1;
273 for (var j = cacheStart; j <
count; j++)
274 this._cacheItems[j] = cacheEntry;
275 this._cacheValid = count - 1;
280 _removeItemAtIndex:
function (aIndex,
aCount) {
282 if (this._filtered) {
285 for (var
i = aIndex;
i < aIndex + removeCount; ++
i) {
286 var item = this._filterSet[
i];
288 for (var j = 0; j < parent.cookies.length; ++j) {
289 if (item == parent.cookies[j]) {
290 parent.cookies.splice(j, 1);
295 this._filterSet.splice(aIndex, removeCount);
299 var item = this._getItemAtIndex(aIndex);
301 this._invalidateCache(aIndex - 1);
305 var parent = this._getItemAtIndex(item.parentIndex);
306 for (var
i = 0;
i < parent.cookies.length; ++
i) {
307 var cookie = parent.cookies[
i];
308 if (item.rawHost == cookie.rawHost &&
309 item.name == cookie.name && item.path == cookie.path)
310 parent.cookies.splice(
i, removeCount);
315 _invalidateCache:
function (aIndex) {
316 this._cacheValid = Math.min(this._cacheValid, aIndex);
319 getCellText:
function (aIndex, aColumn) {
320 if (!this._filtered) {
321 var item = this._getItemAtIndex(aIndex);
324 if (aColumn.id ==
"domainCol")
326 else if (aColumn.id ==
"nameCol")
330 if (aColumn.id ==
"domainCol")
331 return this._filterSet[aIndex].rawHost;
332 else if (aColumn.id ==
"nameCol")
333 return this._filterSet[aIndex].name;
339 get selection () {
return this._selection; },
340 set selection (
val) { this._selection =
val;
return val; },
341 getRowProperties:
function (aIndex, aProperties) {},
343 getColumnProperties:
function (aColumn, aProperties) {},
344 isContainer:
function (aIndex) {
345 if (!this._filtered) {
346 var item = this._getItemAtIndex(aIndex);
347 if (!item)
return false;
348 return item.container;
352 isContainerOpen:
function (aIndex) {
353 if (!this._filtered) {
354 var item = this._getItemAtIndex(aIndex);
355 if (!item)
return false;
360 isContainerEmpty:
function (aIndex) {
361 if (!this._filtered) {
362 var item = this._getItemAtIndex(aIndex);
363 if (!item)
return false;
364 return item.cookies.length == 0;
368 isSeparator:
function (aIndex) {
return false; },
369 isSorted:
function (aIndex) {
return false; },
370 canDrop:
function (aIndex, aOrientation) {
return false; },
371 drop:
function (aIndex, aOrientation) {},
372 getParentIndex:
function (aIndex) {
373 if (!this._filtered) {
374 var item = this._getItemAtIndex(aIndex);
379 if (!item || item.container)
return -1;
380 return item.parentIndex;
384 hasNextSibling:
function (aParentIndex, aIndex) {
385 if (!this._filtered) {
392 var item = this._getItemAtIndex(aIndex);
394 if (item.container) {
395 for (var
i = aIndex + 1;
i < this.rowCount; ++
i) {
396 var subsequent = this._getItemAtIndex(
i);
397 if (subsequent.container)
403 var parent = this._getItemAtIndex(item.parentIndex);
404 if (parent && parent.container)
405 return aIndex < item.parentIndex + parent.cookies.length;
409 return aIndex < this.rowCount - 1;
411 hasPreviousSibling:
function (aIndex) {
412 if (!this._filtered) {
413 var item = this._getItemAtIndex(aIndex);
414 if (!item)
return false;
415 var parent = this._getItemAtIndex(item.parentIndex);
416 if (parent && parent.container)
417 return aIndex > item.parentIndex + 1;
421 getLevel:
function (aIndex) {
422 if (!this._filtered) {
423 var item = this._getItemAtIndex(aIndex);
429 getImageSrc:
function (aIndex, aColumn) {},
430 getProgressMode:
function (aIndex, aColumn) {},
431 getCellValue:
function (aIndex, aColumn) {},
432 setTree:
function (aTree) {},
433 toggleOpenState:
function (aIndex) {
434 if (!this._filtered) {
435 var item = this._getItemAtIndex(aIndex);
437 this._invalidateCache(aIndex);
438 var multiplier = item.open ? -1 : 1;
439 var delta = multiplier * item.cookies.length;
440 this._rowCount += delta;
441 item.open = !item.open;
442 gCookiesWindow._tree.treeBoxObject.rowCountChanged(aIndex + 1, delta);
446 cycleHeader:
function (aColumn) {},
447 selectionChanged:
function () {},
448 cycleCell:
function (aIndex, aColumn) {},
449 isEditable:
function (aIndex, aColumn) {
452 isSelectable:
function (aIndex, aColumn) {
455 setCellValue:
function (aIndex, aColumn,
aValue) {},
456 setCellText:
function (aIndex, aColumn,
aValue) {},
457 performAction:
function (aAction) {},
458 performActionOnRow:
function (aAction, aIndex) {},
459 performActionOnCell:
function (aAction, aindex, aColumn) {}
462 _makeStrippedHost:
function (
aHost) {
464 return formattedHost.substring(0, 4) ==
"www." ? formattedHost.substring(4, formattedHost.length) : formattedHost;
467 _addCookie:
function (aStrippedHost,
aCookie, aHostCount) {
468 if (!(aStrippedHost in this._hosts) || !this._hosts[aStrippedHost]) {
469 this._hosts[aStrippedHost] = { cookies : [],
470 rawHost : aStrippedHost,
474 this._hostOrder.push(aStrippedHost);
478 var c = this._makeCookieObject(aStrippedHost, aCookie);
479 this._hosts[aStrippedHost].cookies.push(c);
482 _makeCookieObject:
function (aStrippedHost,
aCookie) {
483 var host = aCookie.host;
484 var formattedHost = host.charAt(0) ==
"." ? host.substring(1, host.length) : host;
485 var c = {
name : aCookie.name,
486 value : aCookie.value,
487 isDomain : aCookie.isDomain,
489 rawHost : aStrippedHost,
491 isSecure : aCookie.isSecure,
492 expires : aCookie.expires,
498 _loadCookies:
function () {
499 var e = this._cm.enumerator;
500 var hostCount = {
value: 0 };
502 this._hostOrder = [];
503 while (e.hasMoreElements()) {
504 var cookie = e.getNext();
505 if (cookie && cookie instanceof Components.interfaces.nsICookie) {
506 var strippedHost = this._makeStrippedHost(cookie.host);
507 this._addCookie(strippedHost, cookie, hostCount);
512 this._view._rowCount = hostCount.value;
515 formatExpiresString:
function (aExpires) {
517 var
date =
new Date(1000 * aExpires);
518 return this._ds.FormatDateTime(
"", this._ds.dateFormatLong,
519 this._ds.timeFormatSeconds,
527 return this._bundle.getString(
"expireAtEndOfSession");
530 _updateCookieData:
function (aItem) {
531 var seln = this._view.selection;
532 var ids = [
"name",
"value",
"host",
"path",
"isSecure",
"expires"];
535 if (aItem && !aItem.container && seln.count > 0) {
536 properties = {
name: aItem.name,
value: aItem.value, host: aItem.host,
537 path: aItem.path, expires: this.formatExpiresString(aItem.expires),
538 isDomain: aItem.isDomain ? this._bundle.getString(
"domainColon")
539 : this._bundle.getString(
"hostColon"),
540 isSecure: aItem.isSecure ? this._bundle.getString(
"forSecureOnly")
541 : this._bundle.getString(
"forAnyConnection") };
542 for (var
i = 0;
i < ids.length; ++
i)
543 document.getElementById(ids[
i]).disabled =
false;
546 var noneSelected = this._bundle.getString(
"noCookieSelected");
547 properties = {
name: noneSelected,
value: noneSelected, host: noneSelected,
548 path: noneSelected, expires: noneSelected,
549 isSecure: noneSelected };
550 for (
i = 0;
i < ids.length; ++
i)
551 document.getElementById(ids[
i]).disabled =
true;
553 for (var property in properties)
554 document.getElementById(property).value = properties[property];
557 onCookieSelected:
function () {
558 var properties, item;
559 var seln = this._tree.view.selection;
560 if (!this._view._filtered)
561 item = this._view._getItemAtIndex(seln.currentIndex);
563 item = this._view._filterSet[seln.currentIndex];
565 this._updateCookieData(item);
567 var rangeCount = seln.getRangeCount();
568 var selectedCookieCount = 0;
569 for (var
i = 0;
i < rangeCount; ++
i) {
570 var
min = {}; var max = {};
571 seln.getRangeAt(
i, min, max);
572 for (var j = min.value; j <= max.value; ++j) {
573 item = this._view._getItemAtIndex(j);
575 if (item.container && !item.open)
576 selectedCookieCount += item.cookies.length;
577 else if (!item.container)
578 ++selectedCookieCount;
581 var item = this._view._getItemAtIndex(seln.currentIndex);
582 if (item && seln.count == 1 && item.container && item.open)
583 selectedCookieCount += 2;
585 var stringKey = selectedCookieCount == 1 ?
"removeCookie" :
"removeCookies";
586 document.getElementById(
"removeCookie").label = this._bundle.getString(stringKey);
588 document.getElementById(
"removeAllCookies").disabled = this._view._filtered;
589 document.getElementById(
"removeCookie").disabled = !(seln.count > 0);
592 deleteCookie:
function () {
594 # // - Selection always moves to *NEXT* adjacent item unless item
595 # // is last child at a given level in which case it moves to *PREVIOUS*
598 # // Selection Cases (Somewhat Complicated)
600 # // 1) Single cookie selected, host has single child
605 # // Before SelectedIndex: 1 Before RowCount: 3
606 # // After SelectedIndex: 0 After RowCount: 1
608 # // 2) Host selected, host open
610 # // goats.com sldkkfjl
611 # // goat.scom flksj133
614 # // Before SelectedIndex: 0 Before RowCount: 4
615 # // After SelectedIndex: 0 After RowCount: 1
617 # // 3) Host selected, host closed
621 # // Before SelectedIndex: 0 Before RowCount: 2
622 # // After SelectedIndex: 0 After RowCount: 1
624 # // 4) Single cookie selected, host has many children
626 # // goats.com sldkkfjl
630 # // Before SelectedIndex: 2 Before RowCount: 4
631 # // After SelectedIndex: 1 After RowCount: 3
633 # // 5) Single cookie selected, host has many children
636 # // goats.com sldkkfjl
639 # // Before SelectedIndex: 1 Before RowCount: 4
640 # // After SelectedIndex: 1 After RowCount: 3
641 var seln = this._view.selection;
642 var tbo = this._tree.treeBoxObject;
644 if (seln.count < 1)
return;
646 var nextSelected = 0;
647 var rowCountImpact = 0;
648 var deleteItems = [];
649 if (!this._view._filtered) {
650 var ci = seln.currentIndex;
652 var invalidateRow = -1;
653 var item = this._view._getItemAtIndex(ci);
654 if (item.container) {
655 rowCountImpact -= (item.open ? item.cookies.length : 0) + 1;
656 deleteItems = deleteItems.concat(item.cookies);
657 if (!this._view.hasNextSibling(-1, ci))
659 this._view._removeItemAtIndex(ci);
662 var parent = this._view._getItemAtIndex(item.parentIndex);
664 if (parent.cookies.length == 1) {
666 deleteItems.push(item);
667 if (!this._view.hasNextSibling(-1, ci))
669 if (!this._view.hasNextSibling(-1, item.parentIndex))
671 this._view._removeItemAtIndex(item.parentIndex);
672 invalidateRow = item.parentIndex;
675 deleteItems.push(item);
676 if (!this._view.hasNextSibling(-1, ci))
678 this._view._removeItemAtIndex(ci);
681 this._view._rowCount += rowCountImpact;
682 tbo.rowCountChanged(ci, rowCountImpact);
683 if (invalidateRow != -1)
684 tbo.invalidateRow(invalidateRow);
687 var rangeCount = seln.getRangeCount();
688 for (var
i = 0;
i < rangeCount; ++
i) {
689 var
min = {}; var max = {};
690 seln.getRangeAt(
i, min, max);
691 nextSelected = min.value;
692 for (var j = min.value; j <= max.value; ++j) {
693 deleteItems.push(this._view._getItemAtIndex(j));
694 if (!this._view.hasNextSibling(-1, max.value))
697 var delta = max.value - min.value + 1;
698 this._view._removeItemAtIndex(min.value, delta);
699 rowCountImpact = -1 * delta;
700 this._view._rowCount += rowCountImpact;
701 tbo.rowCountChanged(min.value, rowCountImpact);
705 var psvc = Components.classes[
"@mozilla.org/preferences-service;1"]
706 .getService(Components.interfaces.nsIPrefBranch);
707 var blockFutureCookies =
false;
708 if (psvc.prefHasUserValue(
"network.cookie.blockFutureCookies"))
709 blockFutureCookies = psvc.getBoolPref(
"network.cookie.blockFutureCookies");
710 for (
i = 0;
i < deleteItems.length; ++
i) {
711 var item = deleteItems[
i];
712 this._cm.remove(item.host, item.name, item.path, blockFutureCookies);
715 if (nextSelected < 0)
716 seln.clearSelection();
718 seln.select(nextSelected);
723 deleteAllCookies:
function () {
724 this._cm.removeAll();
728 onCookieKeyPress:
function (aEvent) {
729 if (aEvent.keyCode == 46)
733 _lastSortProperty :
"",
734 _lastSortAscending:
false,
735 sort:
function (aProperty) {
736 var ascending = (aProperty == this._lastSortProperty) ? !this._lastSortAscending :
true;
738 if (aProperty ==
"rawHost") {
739 function sortByHost(a, b) {
740 return a.toLowerCase().localeCompare(b.toLowerCase());
742 this._hostOrder.sort(sortByHost);
744 this._hostOrder.reverse();
747 function sortByProperty(a, b) {
748 return a[aProperty].toLowerCase().localeCompare(b[aProperty].toLowerCase());
750 for (var host in this._hosts) {
751 var cookies = this._hosts[host].cookies;
752 cookies.sort(sortByProperty);
757 if (this._view._filtered) {
758 this._view._filterSet.sort(sortByProperty);
760 this._view._filterSet.reverse();
763 this._view._invalidateCache(0);
764 this._view.selection.clearSelection();
765 this._view.selection.select(0);
766 this._tree.treeBoxObject.invalidate();
767 this._tree.treeBoxObject.ensureRowIsVisible(0);
769 this._lastSortAscending = ascending;
770 this._lastSortProperty = aProperty;
773 clearFilter:
function () {
775 this._tree.setAttribute(
"seltype",
"single");
778 this._view._filtered =
false;
779 this._view._rowCount = 0;
780 this._tree.treeBoxObject.rowCountChanged(0, -this._view._filterSet.length);
781 this._view._filterSet = [];
785 this._tree.treeBoxObject.view = this._view;
788 var sortby = this._lastSortProperty;
790 this._lastSortAscending =
false;
791 this.sort(
"rawHost");
794 this._lastSortAscending = !this._lastSortAscending;
799 for (var
i = 0;
i < this._openIndices.length; ++
i)
800 this._view.toggleOpenState(
this._openIndices[
i]);
801 this._openIndices = [];
804 this._view.selection.clearSelection();
805 for (
i = 0;
i < this._lastSelectedRanges.length; ++
i) {
806 var
range = this._lastSelectedRanges[
i];
807 this._view.selection.rangedSelect(range.min, range.max,
true);
809 this._lastSelectedRanges = [];
811 document.getElementById(
"cookiesIntro").value = this._bundle.getString(
"cookiesAll");
814 _cookieMatchesFilter:
function (
aCookie) {
815 return aCookie.rawHost.indexOf(this._view._filterValue) != -1 ||
816 aCookie.name.indexOf(this._view._filterValue) != -1 ||
817 aCookie.value.indexOf(this._view._filterValue) != -1;
820 _filterCookies:
function (aFilterValue) {
821 this._view._filterValue = aFilterValue;
825 if (!currHost)
continue;
826 for (var j = 0; j < currHost.cookies.length; ++j) {
827 var cookie = currHost.cookies[j];
828 if (this._cookieMatchesFilter(cookie))
829 cookies.push(cookie);
835 _lastSelectedRanges: [],
837 _saveState:
function () {
839 var seln = this._view.selection;
840 this._lastSelectedRanges = [];
841 var rangeCount = seln.getRangeCount();
842 for (var
i = 0;
i < rangeCount; ++
i) {
843 var
min = {}; var max = {};
844 seln.getRangeAt(
i, min, max);
845 this._lastSelectedRanges.push({ min: min.value, max: max.value });
849 this._openIndices = [];
850 for (
i = 0;
i < this._view.rowCount; ++
i) {
851 var item = this._view._getItemAtIndex(
i);
852 if (item && item.container && item.open)
853 this._openIndices.push(
i);
858 var
filter = document.getElementById(
"filter").value;
865 if (!view._filtered) {
869 view._filtered =
true;
875 var oldCount = view._rowCount;
879 view._rowCount = view._filterSet.length;
880 gCookiesWindow._tree.treeBoxObject.rowCountChanged(0, view.rowCount);
883 if (view.rowCount > 0)
884 view.selection.select(0);
886 document.getElementById(
"cookiesIntro").value =
gCookiesWindow._bundle.getString(
"cookiesFiltered");
889 setFilter:
function (aFilterString) {
890 document.getElementById(
"filter").value = aFilterString;
894 focusFilterBox:
function () {
895 var
filter = document.getElementById(
"filter");
gImageView getCellProperties
BogusChannel prototype open
this _dialogInput val(dateText)
restoreHistoryPrecursor aCount
_getSelectedPageStyle s i
Array filter(tab.attributes, function(aAttr){return(_this.xulAttributes.indexOf(aAttr.name) >-1);}).forEach(tab.removeAttribute
_updateTextAndScrollDataForFrame aData
sbDeviceFirmwareAutoCheckForUpdate prototype observe