/*** Zim Outliner* @author Anil Bawa <anil@quotesque.net>** Copyright (c) 2007 Anil Bawa-Cavia* Published under an MIT License. See http://www.zimoutliner.com/license.html*//*** Globals*/KEY_ENTER = 13;KEY_UP = 38;KEY_DOWN = 40;KEY_LEFT = 37;KEY_RIGHT = 39;KEY_DELETE = 8;/*** Namespaces*/var Zim = Class.create();Zim.Mixin = Class.create();Zim.Input = Class.create();Zim.Util = Class.create();Zim.Menu = Class.create();/*** Checkbox input*/Zim.Input.Checkbox = function(nodeID){this.nodeID =nodeID;this.id='check_'+nodeID};Zim.Input.Checkbox.prototype = {    nodeID:null,    id:null,    checked:null,    type:'checkbox',    className:'checkbox',    render:function(){        var o = document.createElement('input');        Object.extend(o,this);        return o;    },        onclick:function(){        if(this.checked) {            $(this.nodeID).checkChildren();        } else {            $(this.nodeID).uncheckChildren();        }    }};/*** Editable cells in outline*/Zim.Input.ListCell = function(id) { this.id = id;}Zim.Input.ListCell.prototype = {    id:null,    type:'text',    tabindex:null,    autocomplete:'off',    size:100,    value:null,    render:function(){        var o = document.createElement('input');        Object.extend(o,this);        o.setAttribute('autocomplete',this.autocomplete); //ffox bug workaround for focusing textinput        o.setAttribute('tabindex',this.tabindex);        return o;    },    onkeypress:function(event){        event.node = this.getRow();        //alert(event.charCode || event.keyCode || 0);        Zim.Outline.Modified = true;        var action = 'Press';        var action = (event.ctrlKey) ? 'Fold' : action;        var action = (event.shiftKey && !event.altKey) ? 'Yank' : action;        if(event.keyCode == KEY_ENTER){ this.onPressEnter(event); };        if(event.keyCode == KEY_UP && action!='Fold'){ this.getRow().list['on' + action + 'Up'](event); };        if(event.keyCode == KEY_DOWN && action!='Fold'){ this.getRow().list['on' + action + 'Down'](event); };        if(event.keyCode == KEY_LEFT){ this.getRow().list['on' + action + 'Left'](event); };        if(event.keyCode == KEY_RIGHT){ this.getRow().list['on' + action + 'Right'](event); };        if(event.keyCode == KEY_DELETE){ this.onPressDelete(event); };    },    onblur: function(){        //alert('blurred');        this.selected = false;        this.getRow().removeClassName('highlight');        this.getRow().removeWrapperHighlight();    },    onfocus: function(){        this.selected = true;        if(!this.getRow().hasClassName('expanded') && !this.getRow().hasClassName('collapsed')) this.getRow().addClassName('highlight');        else this.getRow().highlight();    },    getRow:function(){        return $(this.id.substring(5));    },    onPressEnter:function(event){        this.getRow().list.append(this.getRow());    },    onPressDelete:function(event){        if(!this.value.length) {            this.getRow().list.onPressDelete(event);        }    }}Zim.Input.Title = function(id) {this.id = id;};Zim.Input.Title.prototype = {    id:null,    type:'text',    tabindex:null,    autocomplete:'off',    size:80,    value:null,    render:function(){        var container = document.createElement('div');        container.id='titleContainer';        var inner = document.createElement('div');        inner.id='inner';        var o = document.createElement('input');        Object.extend(o,this);        o.setAttribute('autocomplete',this.autocomplete); //ffox bug workaround for focusing textinput        o.setAttribute('tabindex',this.tabindex);        inner.appendChild(o);        container.appendChild(inner);        var bundle = document.createElement('div');        bundle.id = 'Bundle' + this.id;        bundle.className = 'bundle';        container.appendChild(bundle);        return container;    },    onfocus:function(){        this.addClassName('selected');    },    getBundle:function() {        return $('Bundle' + this.id);    },    onblur:function(){        this.removeClassName('selected');    }}/*** Zim Node component*/Zim.Node = function(id){this.id='node' + id;this.name= this.id; };Zim.Node.prototype = {    id:null,    name:null,    list:null,    selected:false,    collapsed:false,    title:null,        onchange: function(){        //alert('changed');    },    blur:function(){        this.getListCell().blur();        this.removeWrapperHighlight();    },        removeWrapperHighlight:function(){        $('wrapper_' + this.id).removeClassName('expandedhighlight');    },    highlight:function(){        $('wrapper_' + this.id).addClassName('expandedhighlight');    },        focus:function(){        this.getListCell().focus();    },        getValue:function(){        return this.getListCell().value;    },    setIndex:function(n){        this.tabindex = n+1;        this.getListCell().setAttribute('tabIndex',this.tabIndex);        //if(this.selected) this.list.selectedIndex = this.index;    },    render:function() {        var node = document.createElement('li');        Object.extend(node,this);        node.addClassName('zimnode');        var oCheckbox = new Zim.Input.Checkbox(this.id);        var div = document.createElement('div');        div.id = 'wrapper_' + this.id;        div.className = 'wrapper';        div.appendChild(oCheckbox.render());        var oDomInput = new Zim.Input.ListCell('cell_' + this.id);        var oWrapper = div.appendChild(oDomInput.render());        var oChild = node.appendChild(div);        if(this.title) oWrapper.value = this.title;        return node;    },        isChecked:function(){        return $('check_'+this.id).checked;    },        check:function(){        $('check_'+this.id).checked = true;        this.checkChildren();    },        uncheck:function(){        $('check_'+this.id).checked = false;        this.uncheckChildren();    },        checkChildren:function(){        if(this.hasChildList()) {            this.getChildListNodes().each(function(oNode) {                oNode.check();            });        }    },        uncheckChildren:function(){        if(this.hasChildList()) {            this.getChildListNodes().each(function(oNode) {                oNode.uncheck();            });        }    },        setChecked:function(){        $('check_'+this.id).checked = 'checked';    },        isCheckedText:function(){        return $('check_'+this.id).checked ? 'checked' : '';    },        expand:function(){        if(this.hasChildListNodes()) {            if(!this.hasClassName('expanded')){                var oDiv = document.createElement('span');                oDiv.className = 'triangle';                oDiv.id = 'triangle_' + this.id;                oDiv.innerHTML = '&#9662;';                oDiv.onclick = this.collapse.bind(this);                if(this.collapsed) this.getElementsByClassName('triangle').shift().remove();                this.collapsed = false;                this.insertBefore(oDiv,$('wrapper_'+this.id));                this.className = 'expanded';            }                        this.getChildListNodes().each(function(oChild,n) {                oChild.show();                oChild.expand();            });        }    },    collapse:function(){        if(this.hasChildListNodes()) {            if(!this.hasClassName('collapsed')) {                var oDiv = document.createElement('span');                oDiv.className = 'triangle collapsed';                oDiv.innerHTML = '&#9656;';                oDiv.onclick = this.expand.bind(this);                this.collapsed = true;                this.getElementsByClassName('triangle').shift().remove();                this.insertBefore(oDiv,$('wrapper_'+this.id));                this.className = 'collapsed';            }                        this.getChildListNodes().each(function(oChild,n) {                oChild.hide();                oChild.collapse();            });        }    },    onmousedown:function(oEvent) {        new Zim.Util.Drag(this.id);    },        clear:function(){        this.remove();    },    show:function() {        this.style.display = 'list-item';    },    hide:function() {        this.style.display = 'none';    },    hasChildListNodes:function(){        return $A(this.childNodes).findAll(function(oNode)        {            return oNode.nodeName == 'UL' ;        }).size() > 0;    },    hasChildList:function(){        return this.hasChildListNodes();    },        getChildList:function(){        return $A(this.childNodes).find(function(oNode)        {            return oNode.nodeName == 'UL' ;        });    },        getChildListNodes:function(){        return $A(this.getChildList().childNodes);    },        getListCell:function(){        //return $A(this.childNodes).find(function(oNode)        //{        //    return oNode.type == 'text';        //});        return $('cell_' + this.id);    },        getParentList:function(){        if(this.hasParentList()){            return this.parentNode;        }    },            getParentListNode:function(){        if(this.hasParentList()){            return this.parentNode.parentNode;        }    },        hasParentList:function(){        return this.parentNode.nodeName =='UL';    },        push:function(oChildNode) {        oChildNode.list = this.list;        this.appendListChild(oChildNode.render());        this.expand();    },        appendListChild:function(oNode){        if(!this.hasChildListNodes()){            var oList = document.createElement('ul');            oList.addClassName('zimlist');            oList.appendChild(oNode);            this.appendChild(oList);        } else {            this.getChildList().appendChild(oNode);        }    },        getListChildren:function(){         return $A(this.getChildList().childNodes).findAll(function(oNode)        {            return oNode.nodeName == 'LI' ;        });    },        hasListChildren:function(){        return $A(this.getChildList().childNodes).findAll(function(oNode)        {            return oNode.nodeName == 'LI' ;        }).size() > 0;    },        checkExpanded:function(){        if(!this.hasListChildren()){            this.removeClassName('expanded');            $('wrapper_' + this.id).removeClassName('expandedhighlight');            this.getChildList().remove();            this.childNodes[0].remove();        }    },        toJSON:function(){        var oChildren = {};        if(this.hasChildListNodes()){            this.getListChildren().each(function(oChild,i){                oChildren[i] = oChild.toJSON();            });        }        return { id:this.id,value:this.getValue(),children:oChildren,_isChecked:this.isCheckedText()};    }};/*** Outline manager*/Zim.Outline = function(id,bundle){    this.id= 'list' + id;    this.container = 'zimContainer' + id;    this.color=bundle.color;    if(bundle.name.length) this.bundle = bundle.name;};Zim.Outline.Save = function(auto) {    if(Zim.Outline.Modified) {        Zim.Outline.Modified = false;        var url = '/list/save/';        var msg = (auto) ? 'Autosaving...' : 'Saving...';        Zim.Menu.setStatus(msg,'info')    }        new Ajax.Request(url, {            method: 'post',            parameters: 'Outline='+Zim.Outline.Current.toJSON(),            onSuccess: Zim.Outline.OnSaveSuccess        });};Zim.Outline.OnSaveSuccess = function(response) {    if (response.responseText.length) {        if(!$('list'+response.responseText) && parseInt(response.responseText) > 0) {            if(Zim.Outline.Current.id == 'list0') {                var newID = 'list' + response.responseText;                $(Zim.Outline.Current.id).id = newID;                Zim.Outline.Current.id = newID;            }        }    }     //$('notice').update(response.responseText);    Zim.Menu.setStatus('Last saved ' + Zim.Time.Print(),'info');}Zim.Outline.prototype = {    id:null,    container:null,    bundle:'Miscellanious',    selectedIndex:null,    nodecount:0,    title:'Untitled List',    push:function(oInput){        oInput.list = this;        $(this.id).appendChild(oInput.render());        $(oInput.id).focus();        this.nodecount++;    },    append:function(oContextNode){        var oInput = new Zim.Node(this.nodecount++);        oInput.list = this;        if(oContextNode) { //middle of the list            oContextNode.getParentList().insertBefore(oInput.render(),oContextNode.nextSibling);        }                $(oInput.id).focus();    },    getSelectedNode:function(){        return this.getNode(this.selectedIndex);    },    getNode:function(n){        try {            return $(this.id).childNodes[n];        }catch(ex) {            return false;        }    },    getTitle:function(){        return $('title').value;    },        setTitle:function(val){        $('title').value = val;        $('title').getBundle().innerHTML = this.bundle;        $('title').getBundle().addClassName(this.color);    },        toJSON:function(){        var oPack = {};        $A($(this.id).childNodes).each(function(oNode,i) {             oPack[i] = oNode.toJSON();        });        return $H({id:this.id,title:this.getTitle(),value:this.getTitle(),_isChecked:false,children:oPack}).toJSON();    },        /**    * Parse nested JSON structure into a zim outline    */    parse:function(oListNode) {        this.setTitle(oListNode.title);        var parent = this;        $A(oListNode.children).each(function(oChild,i) {            parent._parse(oChild);        });        $('node0').focus();    },        _parse:function(oNode,oContextNode) {        var oZimNode = new Zim.Node(this.nodecount++);        var parent = this;        oZimNode.title = oNode.title;        if(oContextNode == undefined) this.push(oZimNode);        else $(oContextNode.id).push(oZimNode);        if(oNode._status=='checked') {            oZimNode.setChecked();        }        $A(oNode.children).each(function(oChild) {            parent._parse(oChild,oZimNode);        });        return oZimNode;    },        removeNode:function(oNode){        oNode.clear();    },    render:function(){        var oElement =document.createElement('ul');        Object.extend(oElement,this);        oTitleInput = new Zim.Input.Title('title');        oTitleInput.value = this.title;        $(this.container).appendChild(oTitleInput.render());        $(this.container).appendChild(oElement);    },    onPressUp:function(event){        var oSelectedNode = event.node;        var oPreviousSibling = oSelectedNode.previousSibling;        var oContextNode = oPreviousSibling;        if(this.isValidNode(oContextNode)) {                while(oContextNode.hasChildListNodes() && !oContextNode.collapsed) {                    oContextNode = oContextNode.getChildListNodes().pop();                }                oSelectedNode.blur();                oContextNode.focus();        } else {            var oPreviousParentNode = oSelectedNode.getParentListNode();            if(this.isValidNode(oPreviousParentNode)){                oSelectedNode.blur();                oPreviousParentNode.focus();            }        }    },    isValidNode:function(oNode){      return (oNode && oNode.nodeName == 'LI');    },        onPressDown:function(event){        var oSelectedNode = event.node;                if(oSelectedNode.hasChildListNodes() && !oSelectedNode.collapsed) {            oSelectedNode.blur();            return oSelectedNode.getChildListNodes()[0].focus();        }                var oNextSibling = oSelectedNode.nextSibling;        if(oNextSibling) {            oSelectedNode.blur();            return oNextSibling.focus();        }        var oContextNode = oSelectedNode;        try{            while(oContextNode.hasParentList()) {                var oNextNode = oContextNode.getParentListNode().nextSibling;                if(this.isValidNode(oNextNode)) {                    oSelectedNode.blur();                    return oNextNode.focus();                } else {                    oContextNode = oContextNode.getParentListNode();                }            }        } catch(ex){};    },    onPressDelete:function(event){        var oPreviousSibling = event.node.previousSibling;        if(oPreviousSibling) {            oPreviousSibling.focus();            this.removeNode(event.node);        } else if(event.node.hasParentList())        {            var oParentNode = event.node.getParentListNode();            try{            if(oParentNode.hasParentList()){                this.removeNode(event.node);                oParentNode.checkExpanded();                oParentNode.focus();            }            } catch(ex){};        }    },    onPressLeft:function(event){    },    onPressRight:function(event){    },    onYankUp:function(event){        var oSelected = event.node;        var oPreviousSibling = oSelected.previousSibling;        if(oPreviousSibling)        {            oSelected.parentNode.insertBefore(oSelected,oPreviousSibling);            oSelected.focus();        }    },    onYankDown:function(event){        var oSelected = event.node;        var oNextSibling = oSelected.nextSibling;        if(oNextSibling) {            if(oNextSibling.nextSibling){                oSelected.getParentList().insertBefore(oSelected,oNextSibling.nextSibling);            } else {                oSelected.getParentList().appendChild(oSelected);            }            oSelected.focus();        }    },    onYankLeft:function(event){        var oNode = event.node;        var oParent = oNode.getParentListNode();        if(oNode.hasParentList()){            try{            oNode.parentNode.parentNode.getParentList().insertBefore(oNode,oNode.parentNode.parentNode.nextSibling);            oParent.checkExpanded();            oNode.focus();            } catch(ex){};        }    },    onYankRight:function(event){        var oNode = event.node;        var oPreviousNode = oNode.previousSibling;        if(oPreviousNode){            oPreviousNode.appendListChild(oNode);            oPreviousNode.expand();            oNode.focus();        }    },        onFoldLeft:function(event){        var oNode = event.node;        oNode.collapse();    },        onFoldRight:function(event){        var oNode = event.node;        oNode.expand();    }};Zim.Outline.Modified = true;/*** Utils*/Zim.Util.Drag = function(id) {this.init(id);};Zim.Util.Drag.prototype = {    scroll:true,    target:null,    timeThreshold:100,    _active:false,        init:function(id) {        if(id) {            this.target = $(id);            this._onLoad();            setTimeout(this.startDrag.bind(this),this.timeThreshold);        }    },        startDrag:function(x,y) {        if(this._active) {            //alert('start drag');            this.target.style.cursor = 'pointer';        }    },        stopDrag:function() {        Event.stopObserving(window,'mouseup');        Event.unloadCache();        this._active = false;    },        onDrag:function(event){    },        onDragOver:function(event,id){            },        onDragOut:function(event,id){    },        _onLoad:function() {        //Event.observe(window, 'mouseup',this.stopDrag.bind(this));        this._active=true;    } };Zim.Bundle = {};Zim.Bundle.Title = function(id,title,color){ this.bundleID = id;this.value=title;this.id='name'+this.bundleID;this.color=color;};Zim.Bundle.Title.prototype= {    value:null,    type:'text',    id:null,    color:null,    bundleID:null,    tabindex:null,    autocomplete:'off',    size:60,    value:null,    onfocus:function(){        this.onfocusvalue = this.value;        this.removeClassName('name');        this.addClassName('selected');    },    onblur:function(){        this.addClassName('name');        this.removeClassName('selected');        if(this.onfocusvalue != this.value){            new Zim.Command.Bundle.Title.Save(this.bundleID,this.value);        }    },    render:function(){        var div = document.createElement('div');        var input = document.createElement('input');        div.className = 'title';        input.addClassName('name');        input.setAttribute('autocomplete',this.autocomplete); //ffox bug workaround for focusing textinput        input.setAttribute('tabindex',this.tabindex);        Object.extend(input,this);        div.appendChild(input);        $('bundle'+this.bundleID).appendChild(div);    }}/*** @package Menu* @desc Context-aware JS menu for all zim screens*/Zim.Menu.submenu = $A(['Zim','File','Shortcuts','View','Account']);Zim.Menu.Locations = {'Zim':50,'File':97,'View':188,'Shortcuts':142,'Account':240};Zim.Menu.Width = {'Zim':140,'File':100,'View':140,'Shortcuts':165,'Account':140};Zim.Menu.selectedLists = $A([]);Zim.Menu.selected = false;Zim.Menu.focused = false;Zim.Menu.show=function(selectedMenu) {    Zim.Menu.active = true;    if($('friendlynotice')) {        $('friendlynotice').style.display = 'none';    }    if(selectedMenu == undefined) var selectedMenu = Zim.Menu.selected;    //console.log(selectedMenu);    if($(selectedMenu).style.display=='none') {        Zim.Menu.getUnselected(selectedMenu).each(function(unselectedMenuDiv) {            Zim.Menu.deselect(unselectedMenuDiv);        });        Zim.Menu.select(selectedMenu);    } else {        //$('submenuContainer').style.height='';        Zim.Menu.deselect(selectedMenu,true);    }};Zim.Menu.getUnselected=function(selectedMenu){    if(!selectedMenu) selectedMenu = Zim.Menu.selected;    return (Zim.Menu.submenu.select(function(menuDiv) {            return menuDiv != selectedMenu;        }));}Zim.Menu.select=function(div) {    Zim.Menu.selected = div;    Zim.Menu.focused = true;    $(div).style.width = Zim.Menu.Width[div] + 'px';    $('title_'+div).addClassName('selected');    $('title_'+div).blur();    $(div).style.left = Zim.Menu.Locations[div] + 'px';    $(div).style.display = 'inline';    Zim.Menu.onFocus(div);    $('title_'+div).onmouseover=function(){ Zim.Menu.active=true;};    $('title_'+div).onclick=function(){Zim.Menu.show(div); };    $('title_'+div).onmouseout=function(){ Zim.Menu.active=false;$('title_'+div).style.cursor='pointer'; };        //Effect.Fade(div,{duration:.3,afterFinish:Zim.Menu.onSelectComplete,from:0.0,to:1.0});};Zim.Menu.onFocus=function(selectedMenu){    Zim.Menu.getUnselected(selectedMenu).each(function(menu){        $('title_'+menu).onmouseover=function(){Zim.Menu.active=true;Zim.Menu.show(menu); };        $('title_'+menu).onmouseout=function(){ Zim.Menu.active=false;};        $('title_'+menu).onclick = function(){};        $('title_'+menu).style.cursor='default';    });}Zim.Menu.onBlur=function(deselected){    Zim.Menu.submenu.each(function(div) {        $('title_'+div).onmouseover=function(){ Zim.Menu.active=true;};        $('title_'+div).onclick=function(){Zim.Menu.show(div); };        $('title_'+div).onmouseout=function(){ Zim.Menu.active=false; };        $('title_'+div).style.cursor='pointer';    });}Zim.Menu.onSelectComplete = function() {    //var div = Zim.Menu.selected;    //$('title_'+div).onclick = function() { Zim.Menu.show(div); };}Zim.Menu.onDeselectComplete=function(div) {    //$('title_'+div).onclick = function() { Zim.Menu.show(div); };}Zim.Menu.deselect=function(div,fade) {    try {        //Zim.Menu.onDeselectComplete(div);        if(fade) {            //console.log('offset '+window.pageYOffset);            Effect.Fade(div,{duration:.1,from:1.0,to:0.0});            Zim.Menu.focused = false;            Zim.Menu.onBlur();        } else {            $(div).style.display = 'none';                    }        //Effect.Fade(div,{duration:.3,from:1.0,to:0.0,afterFinish:function(){ Zim.Menu.onDeselectComplete(selectedMenu)}});        $('title_'+div).removeClassName('selected');        $('title_'+div).blur();    } catch(ex){};};Zim.Menu.getOption=function(opt) {    return $(opt);}Zim.Menu.setStatus=function(status,level) {    if(!$('status').hasClassName(level)) $('status').toggleClassName(level);    $('status').innerHTML = status;}Zim.Menu.onSelectList=function(id) {    if($('check_'+id).checked) {    Zim.Menu.getOption('delete').enable();    Zim.Menu.selectedLists.push(id);    $('list'+id).addClassName('selected');    } else {        Zim.Menu.selectedLists = Zim.Menu.selectedLists.reject(function(listID) { return listID == id});        $('list'+id).removeClassName('selected');        if(Zim.Menu.selectedLists.size() == 0) {            Zim.Menu.getOption('delete').disable();        }    }}Zim.Menu.Submenu = function(id,title) { this.id=id;this.title=title;this.aOption=[];};Zim.Menu.Submenu.prototype = {    id:null,    title:null,    aOption:[],    container:'submenuContainer',        addOption:function(opt) {      this.aOption.push(new Zim.Menu.Option(opt));     },        onmouseover:function(){      Zim.Menu.active = true;      },    onmouseout:function(){      Zim.Menu.active = false;      },        render:function() {        var section = document.createElement('div');        Object.extend(section,this);        section.addClassName('submenu');        var subContainer = document.createElement('div');        var contextContainer = document.createElement('ul');        $A(this.aOption).each(function(oOption,i) {            contextContainer.appendChild(oOption.render());        });        subContainer.appendChild(contextContainer);        section.appendChild(subContainer);        var sectionDiv = $(this.container).appendChild(section);        sectionDiv.style.display='none';        return section;    }};Zim.Menu.Option = function(oOptions) { this.id=oOptions.id;this.label=oOptions.title;this.command = oOptions.command};Zim.Menu.Option.prototype = {    id:null,    label:null,    enabled:false,    command:null,        enable:function() {        this.enabled = true;        this.style.cursor='pointer';        this.addClassName('command');        this.removeClassName('disabled');    },    disable:function() {        this.enabled = false;        this.addClassName('disabled');        this.removeClassName('command');        this.style.cursor='';    },    onclick:function() {        if(this.enabled) {            Zim.Menu.deselect(Zim.Menu.selected,true);            this.command.execute();        }    },    /*onmouseover:function(){      Zim.Menu.active = true;      },    onmouseout:function(){      Zim.Menu.active = false;      },*/    render:function(){        var oDiv = document.createElement('li');        Object.extend(oDiv,this);        oDiv.innerHTML = this.label;        if(!this.enabled) oDiv.disable();        return oDiv;    }};Zim.Time = function(){};Zim.Time.Print = function() {    var Stamp = new Date();    var Hours = Stamp.getHours();    var Mins = Stamp.getMinutes();    var Time = (Hours >= 12)  ? 'PM' : 'AM';    if (Hours > 12) Hours-=12;    if (Hours == 0) Hours = 12;    if (Mins < 10) Mins = "0" + Mins;    return Hours.toString() + ':' + Mins.toString() + ' '+Time;};Event.observe(window, 'mousedown', function() {    if(!Zim.Menu.active) {        Zim.Menu.deselect(Zim.Menu.selected,true);    }});