Closed
Bug 385641
Opened 17 years ago
Closed 17 years ago
general webpage load considerably enhanced
Categories
(Firefox :: File Handling, enhancement)
Tracking
()
VERIFIED
INVALID
People
(Reporter: holpo, Unassigned)
Details
Attachments
(1 file)
13.84 KB,
application/x-javascript
|
Details |
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.4) Gecko/20070518 Firefox/2.0.0.3 Sulfur/0.8.0.99 Build Identifier: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.4) Gecko/20070518 Firefox/2.0.0.3 Sulfur/0.8.0.99 Through analyzing leaks and error console messages on the workings of GetElementsById and GetElementsByTagname the browser does not process the events in a selected way, this hampers the onload of pages. After installing the JavaScript SelectableElementsTable both on dial-up as on broadband the page load was faster by heaps. Reproducible: Always Steps to Reproduce: 1. Normal hampered page load 2. Install SelectableElementsTable.js in the components folder 3. Faster page load Actual Results: Many reported faster load. The code to mend the bug: [code] /* SelectableElementsTable.js function SelectableElements(oElement, bMultiple) { if (oElement == null) return; this._htmlElement = oElement; this._multiple = Boolean(bMultiple); this._selectedItems = []; this._fireChange = true; var oThis = this; this._onclick = function (e) { if (e == null) e = oElement.ownerDocument.parentWindow.event; oThis.click(e); }; if (oElement.addEventListener) oElement.addEventListener("click", this._onclick, false); else if (oElement.attachEvent) oElement.attachEvent("onclick", this._onclick); } SelectableElements.prototype.setItemSelected = function (oEl, bSelected) { if (!this._multiple) { if (bSelected) { var old = this._selectedItems[0] if (oEl == old) return; if (old != null) this.setItemSelectedUi(old, false); this.setItemSelectedUi(oEl, true); this._selectedItems = [oEl]; this.fireChange(); } else { if (this._selectedItems[0] == oEl) { this.setItemSelectedUi(oEl, false); this._selectedItems = []; } } } else { if (Boolean(oEl._selected) == Boolean(bSelected)) return; this.setItemSelectedUi(oEl, bSelected); if (bSelected) this._selectedItems[this._selectedItems.length] = oEl; else { // remove var tmp = []; var j = 0; for (var i = 0; i < this._selectedItems.length; i++) { if (this._selectedItems[i] != oEl) tmp[j++] = this._selectedItems[i]; } this._selectedItems = tmp; } this.fireChange(); } }; // This method updates the UI of the item SelectableElements.prototype.setItemSelectedUi = function (oEl, bSelected) { if (bSelected) addClassName(oEl, "selected"); else removeClassName(oEl, "selected"); oEl._selected = bSelected; }; SelectableElements.prototype.getItemSelected = function (oEl) { return Boolean(oEl._selected); }; SelectableElements.prototype.fireChange = function () { if (!this._fireChange) return; if (typeof this.onchange == "string") this.onchange = new Function(this.onchange); if (typeof this.onchange == "function") this.onchange(); }; SelectableElements.prototype.click = function (e) { var oldFireChange = this._fireChange; this._fireChange = false; // create a copy to compare with after changes var selectedBefore = this.getSelectedItems(); // is a cloned array // find row var el = e.target != null ? e.target : e.srcElement; while (el != null && !this.isItem(el)) el = el.parentNode; if (el == null) { // happens in IE when down and up occur on different items this._fireChange = oldFireChange; return; } var rIndex = el; var aIndex = this._anchorIndex; // test whether the current row should be the anchor if (this._selectedItems.length == 0 || (e.ctrlKey && !e.shiftKey && this._multiple)) { aIndex = this._anchorIndex = rIndex; } if (!e.ctrlKey && !e.shiftKey || !this._multiple) { // deselect all var items = this._selectedItems; for (var i = items.length - 1; i >= 0; i--) { if (items[i]._selected && items[i] != el) this.setItemSelectedUi(items[i], false); } this._anchorIndex = rIndex; if (!el._selected) { this.setItemSelectedUi(el, true); } this._selectedItems = [el]; } // ctrl else if (this._multiple && e.ctrlKey && !e.shiftKey) { this.setItemSelected(el, !el._selected); this._anchorIndex = rIndex; } // ctrl + shift else if (this._multiple && e.ctrlKey && e.shiftKey) { // up or down? var dirUp = this.isBefore(rIndex, aIndex); var item = aIndex; while (item != null && item != rIndex) { if (!item._selected && item != el) this.setItemSelected(item, true); item = dirUp ? this.getPrevious(item) : this.getNext(item); } if (!el._selected) this.setItemSelected(el, true); } // shift else if (this._multiple && !e.ctrlKey && e.shiftKey) { // up or down? var dirUp = this.isBefore(rIndex, aIndex); // deselect all var items = this._selectedItems; for (var i = items.length - 1; i >= 0; i--) this.setItemSelectedUi(items[i], false); this._selectedItems = []; // select items in range var item = aIndex; while (item != null) { this.setItemSelected(item, true); if (item == rIndex) break; item = dirUp ? this.getPrevious(item) : this.getNext(item); } } // find change!!! var found; var changed = selectedBefore.length != this._selectedItems.length; if (!changed) { for (var i = 0; i < selectedBefore.length; i++) { found = false; for (var j = 0; j < this._selectedItems.length; j++) { if (selectedBefore[i] == this._selectedItems[j]) { found = true; break; } } if (!found) { changed = true; break; } } } this._fireChange = oldFireChange; if (changed && this._fireChange) this.fireChange(); }; SelectableElements.prototype.getSelectedItems = function () { //clone var items = this._selectedItems; var l = items.length; var tmp = new Array(l); for (var i = 0; i < l; i++) tmp[i] = items[i]; return tmp; }; SelectableElements.prototype.isItem = function (node) { return node != null && node.nodeType == 1 && node.parentNode == this._htmlElement; }; SelectableElements.prototype.destroy = function () { if (this._htmlElement.removeEventListener) this._htmlElement.removeEventListener("click", this._onclick, false); else if (this._htmlElement.detachEvent) this._htmlElement.detachEvent("onclick", this._onclick); this._htmlElement = null; this._onclick = null; this._selectedItems = null; }; /* Traversable Collection Interface */ SelectableElements.prototype.getNext = function (el) { var n = el.nextSibling; if (n == null || this.isItem(n)) return n; return this.getNext(n); }; SelectableElements.prototype.getPrevious = function (el) { var p = el.previousSibling; if (p == null || this.isItem(p)) return p; return this.getPrevious(p); }; SelectableElements.prototype.isBefore = function (n1, n2) { var next = this.getNext(n1); while (next != null) { if (next == n2) return true; next = this.getNext(next); } return false; }; /* End Traversable Collection Interface */ /* Indexable Collection Interface */ SelectableElements.prototype.getItems = function () { var tmp = []; var j = 0; var cs = this._htmlElement.childNodes; var l = cs.length; for (var i = 0; i < l; i++) { if (cs[i].nodeType == 1) tmp[j++] = cs[i] } return tmp; }; SelectableElements.prototype.getItem = function (nIndex) { var j = 0; var cs = this._htmlElement.childNodes; var l = cs.length; for (var i = 0; i < l; i++) { if (cs[i].nodeType == 1) { if (j == nIndex) return cs[i]; j++; } } return null; }; SelectableElements.prototype.getSelectedIndexes = function () { var items = this.getSelectedItems(); var l = items.length; var tmp = new Array(l); for (var i = 0; i < l; i++) tmp[i] = this.getItemIndex(items[i]); return tmp; }; SelectableElements.prototype.getItemIndex = function (el) { var j = 0; var cs = this._htmlElement.childNodes; var l = cs.length; for (var i = 0; i < l; i++) { if (cs[i] == el) return j; if (cs[i].nodeType == 1) j++; } return -1; }; /* End Indexable Collection Interface */ function addClassName(el, sClassName) { var s = el.className; var p = s.split(" "); if (p.length == 1 && p[0] == "") p = []; var l = p.length; for (var i = 0; i < l; i++) { if (p[i] == sClassName) return; } p[p.length] = sClassName; el.className = p.join(" "); } function removeClassName(el, sClassName) { var s = el.className; var p = s.split(" "); var np = []; var l = p.length; var j = 0; for (var i = 0; i < l; i++) { if (p[i] != sClassName) np[j++] = p[i]; } el.className = np.join(" "); } function filterTestsForBrowser() { var testTables = document.getElementsByTagName("table"); for (var i = 0; i < testTables.length; i++) { filterTestTableForBrowser(testTables[i]); } } function filterTestTableForBrowser(testTable) { for(rowNum = testTable.rows.length - 1; rowNum >= 0; rowNum--) { var row = testTable.rows[rowNum]; var filterString = row.getAttribute("if"); if (filterString && !eval(filterString)) { testTable.deleteRow(rowNum) } } } function filterTestsForBrowser() { var testTables = document.getElementsByTagName("table"); for (var i = 0; i < testTables.length; i++) { filterTestTableForBrowser(testTables[i]); } } function filterTestTableForBrowser(testTable) { for(rowNum = testTable.rows.length - 1; rowNum >= 0; rowNum--) { var row = testTable.rows[rowNum]; var filterString = row.getAttribute("if"); if (filterString && !eval(filterString)) { testTable.deleteRow(rowNum) } } } window.onload=filterTestsForBrowser; window.onload=filterTestsForBrowser; function filter2 (phrase, _id){ var words = phrase.value.toLowerCase().split(" "); var table = document.getElementById(_id); var ele; for (var r = 1; r < table.rows.length; r++){ ele = table.rows[r].innerHTML.replace(/<[^>]+>/g,""); var displayStyle = 'none'; for (var i = 0; i < words.length; i++) { if (ele.toLowerCase().indexOf(words[i])>=0) displayStyle = ''; else { displayStyle = 'none'; break; } } table.rows[r].style.display = displayStyle; } } function filter (term, _id, cellNr){ var suche = term.value.toLowerCase(); var table = document.getElementById(_id); var ele; for (var r = 1; r < table.rows.length; r++){ ele = table.rows[r].cells[cellNr].innerHTML.replace(/<[^>]+>/g,""); if (ele.toLowerCase().indexOf(suche)>=0 ) table.rows[r].style.display = ''; else table.rows[r].style.display = 'none'; } } <cfset var tmpHolder = "" /> <cfloop from="1" to="100" index="idx"> <cfset tmpHolder=createObject("component","testChild").init() /> <cfset arrayAppend(arrayToReturn,tmpHolder) /> </cfloop> function filter( list, if_func ) { var filtered_list = [] for ( var i = 0; i < list.length; ++i ) { var x = list[i] if ( null == if_func || if_func( x ) ) filtered_list.push( x ) } return filtered_list; }; return { filter: filter }; } ) function reduce( op, list, init ) { var r = init; for ( var i = 0; i < list.length; ++i ) r = op( r, list[i] ); return r; } return {reduce: reduce}; } ); [/code]
I reported the bug adviced by the admin at mozilla general firefox user forum. The code given here is the actual solution to the bug, we had to create the new bug to present the solution. Can you affirm that adding this code SelectElementsTable.js to the componets folder. The load performance is considerably faster as was reported by many. This is especially important for users in Australia and New Zealand where they have broadband infrastructure problems, but broadband users can also benefit from bringing this code into the firefox components folder. polonus
Comment 3•17 years ago
|
||
I cannot confirm this works on today's trunk. I had errors in Console2 showing it did not start. Failed to load XPCOM component: C:\Program Files\Minefield\components\SelectableElementsTable.js Error: missing = in XML attribute Source file: file:///C:/Program%20Files/Minefield/components/SelectableElementsTable.js Line: 404, Column: 11 Source code: <cfset>
Added that code as an attachment because some people might accidentally copy the [code] [/code] tags at the beginning and end of the code.
I can't confirm this because CNN seems to load faster but most like foxnews, msnbc, neowin.net, usaa.com, digg.com seemed about the same.
Comment 6•17 years ago
|
||
The attachment still contains <cfset> and other coldfusion tags that aren't right for a javascript file. Can I ask what you expect this code to do. The code doesn't contain a valid component so just sticking it in a js file in the app's components directory will have no effect whatsoever. I'm afraid I also cannot understand your explanation of the problem that this is trying to solve.
http://forums.mozillazine.org/viewtopic.php?t=560802 discuses it more
Comment 8•17 years ago
|
||
The forum gives no further technical details. The suggestion is that you are speeding up getElementsById and getElementsByTagName yet the javascript file appears to do nothing with these methods. Here is what the attached javascript does: Creates a js class SelectableElements that is never used anywhere in the code. Creates some functions (addClassName, removeClassName) that are only used by the SelectableElements class. The functions filterTestsForBrowser and filterTestTableForBrowser are created twice which I imagine would throw a JS error. Attempts to (twice) assign filterTestTableForBrowser to window.onload, which should fail since there is no "window" in a component's scope. Creates a filter2 and filter function that are never used anywhere. Includes some extra coldfusion tags that the JS parser should fail on. Creates a second filter function that isn't used anywhere. Includes some trailing junk script that the parser should fail on. Creates a reduce function that isn't used anywhere. At no point does the code include an NSGetModule which is what would be necessary for this code to do any kind of interaction with any part of Firefox outside of it's own scope.
Hi Dave, But when I have the x-javascript inside FF, Firebug gives strict-Error-checking = true QueryInterface () gives Object Did not code this for snake-oil, there must be something in it from where to start, polonus
Comment 10•17 years ago
|
||
Running inside a webpage is very different to running as a component. I'm afraid I don't really follow the rest of your comment though.
Comment 11•17 years ago
|
||
(In reply to comment #9) > Did not code this for snake-oil, there must be something in it from where > to start, Except you didn't code most of it at all... I'm pretty sure Erik wouldn't appreciate seeing his license block chopped off his code and claimed as someone else's work. Most of this script is part of Erik Arvidsson's WebFX library and is designed as a cross-browser (hence the IE-specific appendElement() in the first block) implementation of just as the function name implies: selectable elements. From SelectableElements' constructor you can see that it takes two arguments: an HTMLElement (containing children which this script makes selectable) and a boolean (specifying whether or not to allow multiple selections) from there the code responds to clicks and click+shift/ctrl (for multiple selection) on the parent element's children and sets the selected children(s) class to "selected" (or removes it if already selected). The code following Erik's, if it were free of all the things Mossop pointed out in comment 8 (minus the dead code) would act only on tables and delete rows with an 'if' attribute that eval()s (yuck) to 'false'. Basically this script: - Doesn't parse. - Even if it did parse, it wouldn't load as a component. - Even if it did load as a component, it wouldn't touch content. - Even if it did touch content, it wouldn't do anything because it's not actually used anywhere. This is absolutely invalid. Feel free to reopen with a patch that actually does something and evidence of such.
Status: UNCONFIRMED → RESOLVED
Closed: 17 years ago
Resolution: --- → INVALID
Reporter | ||
Comment 12•17 years ago
|
||
So the verdict fell, leave it at that, the code was redone from public source with the best of intentions, and if it is inactive, I leave it untouched, Thanks for looking into it, polonus
Updated•17 years ago
|
Status: RESOLVED → VERIFIED
You need to log in
before you can comment on or make changes to this bug.
Description
•