DHTML Windows 11

Yesterday I got an email from a lawyer involved in a patent lawsuit regarding DHTML windows. That is internal windows, inside your web browser created using DHTML. I’m almost sure we had DHTML windows in 1997 or 1998. The lawyer is looking for prior art (before Januarey 1st, 1999). I’ve yet to find any proof that we have code for this before the given date. I found generic resize and generic move dated at least in 1998 at http://www.dtek.chalmers.se/~d96erik/webfx/dhtml/. I’m also pretty sure Fredrik Malmer had his first prototype of WebOS in 1998 but It could also be in 1999.

I’m really interested in finding proof that DHTML windows where a known concept before 1999 because I think a patent like this makes no sense what so ever. What’s next? Patent covering insert widget here implemented using insert technology here?

  • Lucas

    Do you have and if so are you allowed to divulge the patent number Erik?

  • http://erik.eae.net Erik Arvidsson

    I do not know the patent number. Can’t patents be searched online?

    I’ll be away for a week so I won’t be able to provide any more info about this in a week.

  • http://www.developer-x.com trs

    Patent on DHTML windows? That really is taking the piss.

    http://patft.uspto.gov/netacgi/nph-Parser?Sect1=PTO2&Sect2=HITOFF&p=1&u=/netahtml/search-bool.html&r=17&f=G&l=50&co1=AND&d=ptxt&s1=dhtml&s2=window&OS=dhtml+AND+window&RS=dhtml+AND+window

    There are patents on this (and lots of similar things) but I doubt they will ever stand up.

  • http://www.gargoyle-design.com Michael R. Havard

    Dan Steinman I believe had a dynamic window widget back in ’97 or ’98. http://www.dansteinman.com/dynduo.

    It might also be worthwhile to check the wayback machine at http://archive.org for references.

    We need to have an internet bake sale to raise some money to buy back our politicians and get them to work on some patent reform.

  • http://thefeed.no/marcus/ Marcus Ramberg

    One of the first examples I can remember of dynamic JS windows was the windowmaker JS demo.

    This must have been back in 96 or 97, it’s still available online here: http://home.austin.rr.com/spork/WindowMaker/ , but it’s written for ns 4.72, and doesn’t work anywhere else.. What can I say, it’s old, but I was really impressed at the time . =)

  • http://fantasybaseball.ws/mlb_scores Zach

    It was mentioned above, but I knew that Steinmans was prior to 99 – http://www.dansteinman.com/dynduo/en/dynwindow.html

    look at the bottom, Copywrite 1998

  • Marcus T.

    A pointer we may use to shoot down this arrogant patent:
    I am not sure of this, but I have read that software can not be pantented if the description is written in directions for an API or source code(e.g.patent for hopping bunny application (list of steps in Visual Basic or C code for non-standards compiler)). Rather, psuedocode and/or a human-readable text description would pass scrutiny. Javascript, DHTML, and the Web Browser may be considered APIs, as you work through them, not with or in them. The patenter would unfairly be standing on the shoulders of giants. Only if he writes an ActiveX control would I find him able to face this argument. I can imagine Microsoft immediately sending a crew of lawyers to destroy this man’s efforts to proprietize theirs’ and others’ technology, of which he is not part of.

  • Joe

    as a former patent examiner, and someone who is skilled in the art, I remmeber the windowmaker demo back before 99. I also think it is obvious to one skilled in the art that making ‘windows’ on a web page would be usefull. Lastly combing that with the XmlHttpRequest object and updating a single window would be obvious also. I’ve got code that does all this, but it does not date before 99. As a web programmer, I find it obvious, and would hate to be tied up for the next 20 year because someone else gets a patent on this. It would greatly hinder the growth of the web.

  • Joe

    FYI:

    I found this on my system today while futzings around. I’m not sure if you still need to fight this patent thing, but this may help. Its copyright 1998.

    Joe

    // ALAPI Window
    // Author: Matti Hultstrand matti@alapi.com
    // Copyright 1998 Icon Medialab, Inc. All rights reserved.
    // For documentation and more objects see http://www.alapi.com

    function nsBeginDrag(e) {
    if (e.target != “[object Image]“) {
    this.captureEvents(Event.MOUSEMOVE);
    this.onmousemove=this.parentO.nsDrag;
    this.parentO.winLayer.oldX= e.pageX;
    this.parentO.winLayer.oldY= e.pageY;
    this.parentO.winLayer.zIndex=(++win.prototype.HzIndex);
    }
    this.routeEvent(e);
    return false;
    }

    function nsEndDrag(e) {
    this.onmousemove=null;
    this.releaseEvents(Event.MOUSEMOVE);
    return false;
    }

    function nsDrag(e) {
    this.parentO.winLayer.moveBy(e.pageX – this.parentO.winLayer.oldX, e.pageY – this.parentO.winLayer.oldY);
    this.parentO.winLayer.oldX = e.pageX;
    this.parentO.winLayer.oldY = e.pageY;
    }

    function nsWinShow() {
    this.winLayer.visibility = “show”;
    }

    function nsWinHide(e) {
    this.parentO.winLayer.visibility = “hide”;
    window.releaseEvents(e);
    return true;
    }

    function nsWindUp(e) {
    if (this.parentO.stArrow == “MAX”) {
    this.parentO.winLayer.clip.height = this.parentO.bar.clip.height +2
    this.parentO.userArea.visibility=false;
    this.parentO.arrowUp.document.images[0].src= this.parentO.maxImg;
    }
    else {
    this.parentO.winLayer.clip.height = this.parentO.height;
    this.parentO.userArea.visibility=true;
    this.parentO.arrowUp.document.images[0].src= this.parentO.minImg;
    }

    this.parentO.stArrow= (this.parentO.stArrow==”MAX”)? “MIN” :”MAX”;
    this.routeEvent(e);
    return true;
    }

    function moveAbove() {
    this.parentO.winLayer.zIndex=(++win.prototype.HzIndex);
    }

    function nsResizeBy(x,y) {
    if (this.width +x > this.closeCross.document.width + this.arrowUp.document.width +10 && this.height +x > this.barHeight) {
    this.width += x;
    this.height += y;
    this.winLayer.clip.width = this.width;
    this.winLayer.clip.height = this.height;
    this.userArea.clip.width = this.width -2;
    this.userArea.clip.height = this.height – this.userArea.top -1;
    this.bar.clip.width = this.width -2;
    this.arrowUp.left = this.width -13;
    }
    }

    function nsResizeTo(x,y) {
    this.wResizeBy(x-this.width,y-this.height);
    }

    // IE MOUSE DRAG & DROP

    function ieWindUp() {

    if (this.parentO.stArrow == “MAX”) {
    this.parentO.winLayer.style.height = this.parentO.bar.style.pixelHeight +2;
    this.parentO.userArea.style.visibility=”hidden”;
    event.srcElement.src = this.parentO.maxImg;
    } else {
    this.parentO.winLayer.style.height = this.style.parentO.height;
    this.parentO.userArea.style.visibility=”visible”;
    event.srcElement.src = this.parentO.minImg;

    }
    this.parentO.stArrow= (this.parentO.stArrow==”MAX”)? “MIN” :”MAX”;
    }

    function ieWinHide() {
    if (event.srcElement.tagName == “IMG”)
    this.parentO.winLayer.style.visibility = “hidden”;
    }

    function ieWinShow() {
    this.winLayer.style.visibility = “visible”;
    }

    function doMouseMove() {
    var newleft=0, newTop = 0
    if ((event.button==1) && (curElement!=null) ){
    curElement.parentO.winLayer.style.pixelLeft+=(event.clientX-curElement.parentO.oldX);
    curElement.parentO.winLayer.style.pixelTop+=(event.clientY-curElement.parentO.oldY);
    curElement.parentO.oldX=event.clientX;
    curElement.parentO.oldY=event.clientY;
    event.returnValue = false;
    event.cancelBubble = true;
    }
    }

    function doDragStart() { // Don’t do default drag operation.
    if (“DIV”==event.srcElement.tagName)
    event.returnValue=false;
    }

    function doMouseDown() {
    if ((window.event.button==1) && (window.event.srcElement.tagName==”DIV”)
    && (window.event.srcElement.id ==”bar” ||window.event.srcElement.parentElement.id ==”bar”)){
    curElement = event.srcElement;
    curElement.parentO.oldX=event.clientX;
    curElement.parentO.oldY=event.clientY;
    curElement.parentO.winLayer.style.zIndex=(++win.prototype.HzIndex);
    document.onmousemove = doMouseMove;
    }
    if (window.event.srcElement.id ==”userArea”)
    event.srcElement.parentO.winLayer.style.zIndex=(++win.prototype.HzIndex);
    }

    function nsSetProps() {
    this.winLayer = this.layer;
    this.winLayer.parentO = this;
    this.winLayer.bgColor = “black”;
    this.winLayer.clip.height= this.height;
    this.winLayer.clip.width= this.width;
    this.winLayer.oldX = this.winLayer.left;
    this.winLayer.oldY = this.winLayer.top;

    //Create the bar

    this.bar = this.winLayer.document.layers[0];
    this.bar.top = 1;
    this.bar.left = 1;
    this.bar.bgColor = this.barColor;
    this.bar.clip.width= this.width-2;
    this.bar.clip.height= this.barHeight;
    this.bar.document.parentO=this;

    //Event Handling for the bar
    this.bar.document.captureEvents(Event.MOUSEUP|Event.MOUSEDOWN);
    this.bar.document.onmousedown=nsBeginDrag;
    this.bar.document.onmouseup=nsEndDrag;
    //Create the exit cross
    if (this.exit) {
    this.closeCross = this.bar.document.layers[0];
    this.closeCross.parentO=this;
    this.closeCross.top = -2;
    this.closeCross.left = 2;

    //Hide the window
    this.closeCross.captureEvents(Event.MOUSEDOWN);
    this.closeCross.onmousedown=nsWinHide;
    }

    //Create the arrows
    if (this.arrow) {
    this.arrowUp = this.bar.document.layers[1];
    this.arrowUp.parentO=this;
    this.arrowUp.left = this.width -13;
    this.arrowUp.top = -2;

    //Event Handling menu up..

    this.arrowUp.captureEvents(Event.MOUSEDOWN);
    this.arrowUp.onmousedown= nsWindUp;
    }

    // Create the UserArea

    this.userArea = this.winLayer.document.layers[1];
    this.userArea.top = this.barHeight +1;
    this.userArea.left = 1;

    if (this.bgImage == null)
    this.userArea.bgColor = this.bgColor;
    else
    this.userArea.background.src = this.bgImage;

    this.userArea.clip.width= this.width-2;
    this.userArea.clip.height= this.height – this.userArea.top -1;
    this.userArea.document.parentO = this;
    this.userArea.document.onmousedown = moveAbove
    }

    var curElement;

    function setIEProps() {
    this.winLayer = this.layer;
    this.winLayer.style.clip = “rect(0 ” + this.width + ” ” + this.height + ” 0)”;
    this.winLayer.style.backgroundColor = “black”;

    this.bar = this.layer.children(0);
    this.bar.style.top = 1
    this.bar.style.left = 1;
    this.bar.style.backgroundColor = this.barColor;
    this.bar.style.pixelWidth = this.width -2;
    this.bar.style.pixelHeight = this.barHeight;
    this.bar.parentO = this;

    this.closeCross = this.layer.children(0).children(0);
    this.closeCross.style.pixelTop = -2;
    this.closeCross.style.pixelLeft = 2;
    this.closeCross.parentO = this;
    this.closeCross.onmousedown = ieWinHide;

    this.arrowUp = this.layer.children(0).children(1);
    this.arrowUp.image = this.arrowUp.children(0);
    this.arrowUp.style.pixelTop = -2;
    this.arrowUp.style.pixelLeft =this.width -13
    this.arrowUp.style.stArrow = “MIN”;
    this.arrowUp.style.parentO = this;
    this.arrowUp.parentO = this;
    this.arrowUp.onmousedown = ieWindUp;

    this.userArea = this.layer.children(1);
    this.userArea.style.backgroundColor = this.bgColor;
    this.userArea.style.backgroundImage=”url(” + this.bgImage +”)”;
    this.userArea.style.pixelTop = this.barHeight +1;
    this.userArea.style.pixelLeft = 1;
    this.userArea.style.pixelWidth= this.width -2;
    this.userArea.style.pixelHeight= this.height – this.barHeight -2;
    this.userArea.parentO = this;

    document.ondragstart = doDragStart;
    document.onmousedown = doMouseDown;
    document.onmouseup = new Function(“curElement=null; document.onmousemove=null;”)
    }

    function ieResizeBy(x,y) {
    if (this.width +x > this.closeCross.offsetWidth + this.arrowUp.offsetWidth +10 && this.height +x > this.barHeight) {
    this.width += x;
    this.height += y;
    this.winLayer.style.width = this.width;
    this.winLayer.style.height = this.height;
    this.winLayer.style.clip = “rect(0 ” + this.width + ” ” + this.height + ” 0)”;
    this.userArea.style.width = this.width -2;
    this.userArea.style.height = this.height – this.userArea.style.pixelTop -1
    this.userArea.style.clip = “rect(0 ” + this.userArea.style.width + ” ” + this.userArea.style.height + ” 0)”;
    this.bar.style.width = this.width -2;
    this.bar.style.height = this.barHeight;
    this.bar.style.clip = “rect(0 ” + this.userArea.style.width + ” ” + this.barHeight + ” 0)”;
    this.arrowUp.style.pixelLeft = this.width -13;
    }
    }

    function ieResizeTo(x,y) {
    this.wResizeBy(x-this.width,y-this.height);
    }

    function win(layer, exit, arrow, barColor, bgColor, bgImage, minImg, maxImg, closeImg) {
    this.netscape =((navigator.appName == Netscape) && (parseInt(navigator.appVersion) == 4));
    this.layer = layer;
    this.exit = exit;
    this.arrow = arrow;
    this.bgColor = bgColor;
    this.bgImage = bgImage;

    this.barColor = (barColor != null) ? barColor : “#000084″;
    this.stArrow= “MAX”;
    this.barHeight = 15;
    this.blurColor = “#848284″;
    this.oldX=0;
    this.oldY=0;
    this.maxImg=maxImg;
    this.minImg=minImg;
    this.closeImg=closeImg;

    // public method
    if (this.netscape) {
    this.xpos = this.layer.left;
    this.ypos = this.layer.top;
    this.width = this.layer.clip.width;
    this.height = this.layer.clip.height;
    this.wResizeTo = nsResizeTo;
    this.wResizeBy = nsResizeBy;
    this.windUp = nsWindUp;
    this.winShow = nsWinShow;
    this.winHide = nsWinHide;
    this.nsBeginDrag= nsBeginDrag;
    this.nsEndDrag= nsEndDrag;
    this.nsDrag = nsDrag;
    this.setProps = nsSetProps;
    win.prototype.HzIndex=this.layer.zIndex;
    } else {
    this.xpos = this.layer.style.pixelLeft;
    this.ypos = this.layer.style.pixelTop;
    this.width = this.layer.style.pixelWidth;
    this.height = this.layer.style.pixelHeight;

    this.wResizeTo = ieResizeTo;
    this.wResizeBy = ieResizeBy;
    this.setProps = setIEProps
    this.winShow = ieWinShow;
    win.prototype.HzIndex=this.layer.style.zIndex;
    }
    this.setProps();
    }

  • http://flashy.hopto.org bound

    Patent on DHTML windows, only in americna ! why dont you Patent each letter insted ?

  • http://erik.eae.net Erik Arvidsson

    boubd: I think it was a UK company ;-)