Bug #822
closedBug: Frequently using WTableView make "Wt internal error : 80020101" in IE8 !
0%
Description
hi,
frequently using WTableView make "Wt internal error : 80020101" in IE8 !
i finally catch the bug!
new WTableView and WTableView::setHeaderWidth() will call addCssText() function in Wt.js
look at the code:
...
/* IE & Konqueror */
this.addCssText = function(cssText) {
var s = document.getElementById('Wt-inline-css');
if (!s) {
s = document.createElement('style');
s.id = 'Wt-inline-css';
document.getElementsByTagName('head')[0].appendChild(s);
}
if (!s.styleSheet) { // Konqueror
var t = document.createTextNode(cssText);
s.appendChild(t);
} else {
var ss = document.createElement('style');
s.parentNode.insertBefore(ss, s);
ss.styleSheet.cssText = cssText;
}
};
...
this code preppend the
css stylesheet
node
before "Wt-inline-css" node again and again to the html DOM tree, like this:
<html>
<head>
...
<style>css stylesheet</style>
<style>css stylesheet</style>
<style>css stylesheet</style>
<style>css stylesheet</style>
<style>css stylesheet</style>
...
<style id="Wt-inline-css" type="text/css">css stylesheet</style>
</head>
...
</html>
but after this.addCssText() function is called 28 times,
at the meantime,
css stylesheet
are added to 28 nodes
it will make crash in this line:
ss.styleSheet.cssText = cssText;
ss.sytleSheet will be null
(may be a bug of IE8 when document.createElement('style') )
MS IE8 will show debug message error:
line: 1123
error: 'styleSheet' is null or not an object
i can provide complete cpp test code to repeat the error:
#include <Wt/WApplication>
#include <Wt/WContainerWidget>
#include <Wt/WWidget>
#include <Wt/WPushButton>
#include <Wt/WMessageBox>
#include <Wt/WStandardItemModel>
#include <Wt/WTableView>
#include <Wt/WBreak>
using namespace Wt;
class TestApplication : public Wt::WApplication
{
private:
WContainerWidget *rootContainer_;
public:
TestApplication(const WEnvironment& env);
void showFirstButton();
void showDataTable();
};
TestApplication::TestApplication(const WEnvironment& env):
WApplication(env),
rootContainer_(NULL)
{
rootContainer_ = new WContainerWidget(root());
showFirstButton();
}
void TestApplication::showFirstButton()
{
rootContainer_->clear();
WPushButton* firstButton = new WPushButton("show the WTableView");
firstButton->resize(WLength(200, WLength::Pixel), WLength(35, WLength::Pixel));
firstButton->clicked().connect(this, &TestApplication::showDataTable);
rootContainer_->addWidget(firstButton);
}
void TestApplication::showDataTable()
{
rootContainer_->clear();
//button
WPushButton* secondButton = new WPushButton("close the WTableView");
secondButton->resize(WLength(200, WLength::Pixel), WLength(35, WLength::Pixel));
secondButton->clicked().connect(this, &TestApplication::showFirstButton);
//table view
WStandardItemModel* model = new WStandardItemModel();
model->insertColumns(0, 4);
model->setHeaderData(0, boost::any(std::string("column 0")));
model->setHeaderData(1, boost::any(std::string("column 1")));
model->setHeaderData(2, boost::any(std::string("column 2")));
model->setHeaderData(3, boost::any(std::string("column 3")));
model->insertRows(0, 4);
for (int i=0; i<4; i++)
for (int j=0; j<4; j++)
{
WString cellData("({1}, {2})");
model->setData(model->index(i, j), boost::any(cellData.arg(i).arg(j)));
}
WTableView* tableView = new WTableView();
tableView->setModel(model);
tableView->setColumnWidth(0, 100);
tableView->setColumnWidth(1, 110);
tableView->setColumnWidth(2, 120);
tableView->setColumnWidth(3, 130);
tableView->resize(WLength(500, WLength::Pixel), WLength(160, WLength::Pixel));
//breaks
WBreak* br1 = new WBreak();
WBreak* br2 = new WBreak();
//collect widgets
rootContainer_->addWidget(secondButton);
rootContainer_->addWidget(br1);
rootContainer_->addWidget(br2);
rootContainer_->addWidget(tableView);
}
WApplication *createApplication(const WEnvironment& env)
{
return new TestApplication(env);
}
int main(int argc, char **argv)
{
return WRun(argc, argv, &createApplication);
}
run the test program
click "show the WTableView" and "close the WTableView" 28 times (totally 56 click)
the error will be shown.
Files
Updated by DQ Qin over 13 years ago
yes, i found the reason
it's IE css limit:
http://support.microsoft.com/kb/262161/en-us
.All style tags after the first 31 style tags are not applied.
.All style rules after the first 4,095 rules are not applied.
i try to change the Wt.js
this.addCssText = function(cssText) {
var s = document.getElementById('Wt-inline-css');
if (!s) {
s = document.createElement('style');
s.id = 'Wt-inline-css';
document.getElementsByTagName('head')[0].appendChild(s);
}
if (!s.styleSheet) { // Konqueror
var t = document.createTextNode(cssText);
s.appendChild(t);
} else {
var ss = s.previousSibling;
if (!ss || ss.tagName.toLowerCase()!='style' || ss.styleSheet.cssText.length > 32*1024)
{
ss = document.createElement('style');
s.parentNode.insertBefore(ss, s);
ss.styleSheet.cssText = cssText;
}
else
{
ss.styleSheet.cssText += cssText;
}
}
the error never occur.
Updated by Koen Deforche over 13 years ago
- Assignee changed from Koen Deforche to Pieter Libin
Hey,
Thanks for the good analysis. Yes, we are aware of this limit in IE and have ran into this limitation previously.
I didn't know a solution so simple existed !
Regards,
koen
Updated by Pieter Libin over 13 years ago
- Status changed from InProgress to Resolved
Hi,
I applied your patch to our local git, and verified that it fixes this issue.
The patch will be pushed to the public git soon.
kind regards,
Pieter
Updated by Koen Deforche over 13 years ago
- Status changed from Resolved to Closed