File:  [LON-CAPA] / modules / damieng / graphical_editor / loncapa_daxe / web / nodes / match_foilgroup.dart
Revision 1.6: download - view: text, annotated - select for diffs
Wed Mar 8 20:31:22 2017 UTC (7 years, 3 months ago) by damieng
Branches: MAIN
CVS tags: HEAD
making sure that getHTMLContentsNode() returns something for foilgroups

/*
  This file is part of LONCAPA-Daxe.

  LONCAPA-Daxe is free software: you can redistribute it and/or modify
  it under the terms of the GNU General Public License as published by
  the Free Software Foundation, either version 3 of the License, or
  (at your option) any later version.

  LONCAPA-Daxe is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.

  You should have received a copy of the GNU General Public License
  along with Daxe.  If not, see <http://www.gnu.org/licenses/>.
*/

part of loncapa_daxe;

/**
 * This is used by MatchResponse for simple UI.
 */
class MatchFoilgroup extends LCDBlock {

  x.Element itemgroupRef;
  x.Element foilRef;
  String simpleFoilNamePrefix = 'foil'; // can be changed to 'Foil'

  MatchFoilgroup.fromRef(x.Element elementRef) : super.fromRef(elementRef) {
    initMatchFoilgroup();
  }

  MatchFoilgroup.fromNode(x.Node node, DaxeNode parent) : super.fromNode(node, parent) {
    initMatchFoilgroup();
    simpleUI = parent is MatchResponse && parent.simpleUI && simpleUIPossibleNoThrow();
    if (simpleUI)
      setupSimpleUI();
  }

  void initMatchFoilgroup() {
    List<x.Element> itemgroupRefs = doc.cfg.elementReferences('itemgroup');
    itemgroupRef = doc.cfg.findSubElement(ref, itemgroupRefs);
    List<x.Element> foilRefs = doc.cfg.elementReferences('foil');
    foilRef = doc.cfg.findSubElement(ref, foilRefs);
  }

  @override
  bool simpleUIPossible() {
    for (DaxeAttr att in attributes) {
      throw new SimpleUIException('foilgroup: ' + LCDStrings.get('attribute_problem') + att.name);
    }
    for (DaxeNode dn=firstChild; dn!= null; dn=dn.nextSibling) {
      if (dn is MatchFoil) {
        if (!dn.simpleUIPossible())
          return false;
      } else if (dn is Itemgroup) {
          if (!dn.simpleUIPossible())
            return false;
      } else if (dn.nodeType != DaxeNode.TEXT_NODE) {
        String title = doc.cfg.elementTitle(dn.ref);
        throw new SimpleUIException(LCDStrings.get('element_prevents') + ' ' + dn.nodeName +
            (title != null ? " ($title)" : ''));
      } else if (dn.nodeValue.trim() != '') {
        return false;
      }
    }
    return true;
  }

  void setupRestrictions() {
    if (restrictedInserts == null)
      restrictedInserts = ['foil'];
  }

  /**
   * Returns the first itemgroup child.
   */
  Itemgroup getItemgroup() {
    for (DaxeNode dn in childNodes) {
      if (dn is Itemgroup)
        return dn;
    }
    return null;
  }

  /**
   * Returns the list of item names.
   */
  List<String> getItemNames() {
    Itemgroup itemGroup = getItemgroup();
    if (itemGroup != null)
      return itemGroup.getItemNames();
    else
      return new List<String>();
  }

  /**
   * Returns the MatchFoil children
   */
  List<MatchFoil> getFoils() {
    List<MatchFoil> list = new List<MatchFoil>();
    for (DaxeNode dn in childNodes) {
      if (dn is MatchFoil)
        list.add(dn);
    }
    return list;
  }

  @override
  void setupSimpleUI() {
    simpleUI = true;
    setupRestrictions();
    if (getFoils().length == 0) {
      // new node from DOM in simpleUI: add a foil if there is none
      addFoil();
    } else {
      MatchFoil foil = getFoils()[0];
      if (foil.getAttribute('name') != null) {
        if (foil.getAttribute('name').startsWith('Foil'))
          simpleFoilNamePrefix = 'Foil';
      }
    }
  }

  @override
  h.Element html() {
    simpleUI = parent is MatchResponse && (parent as MatchResponse).simpleUI;
    if (!simpleUI)
      return super.html();
    setupRestrictions();

    h.DivElement div = new h.DivElement();
    div.id = id;
    div.classes.add('match-foilgroup');
    if (getItemgroup() != null)
      div.append(getItemgroup().html());
    div.append(foilsHtml());
    return div;
  }

  /**
   * Returns the HTML for editing the foils.
   */
  h.Element foilsHtml() {
    h.DivElement div = new h.DivElement();
    div.id = "foils$id";
    div.classes.add('matchresponse-foilgroup');
    div.appendText(LCDStrings.get('foils'));
    h.TableElement table = new h.TableElement();
    for (DaxeNode dn=firstChild; dn!= null; dn=dn.nextSibling) {
      if (dn is! Itemgroup)
        table.append(dn.html());
    }
    div.append(table);
    h.ButtonElement bAdd = new h.ButtonElement();
    bAdd.attributes['type'] = 'button';
    bAdd.text = LCDStrings.get('add_foil');
    bAdd.onClick.listen((h.MouseEvent event) => addUndoableFoil());
    div.append(bAdd);
    return div;
  }

  void updateFoilsHtml() {
    h.document.getElementById("foils$id").replaceWith(foilsHtml());
  }

  @override
  h.Element getHTMLContentsNode() {
    return(h.document.getElementById(id));
  }
  
  @override
  void updateAttributes() {
    if (!simpleUI) {
      super.updateAttributes();
      return;
    }
    updateHTML();
  }

  /**
   * Adds an itemgroup (not using an UndoableEdit)
   */
  void addItemgroup() {
    Itemgroup itemgroup = new Itemgroup.fromRef(itemgroupRef);
    itemgroup.state = 1;
    appendChild(itemgroup);
  }

  /**
   * Adds a foil (not using an UndoableEdit)
   */
  void addFoil() {
    MatchFoil foil = new MatchFoil.fromRef(foilRef);
    foil.setAttribute('name', 'foil1');
    List<String> names = getItemNames();
    if (names.length > 0)
      foil.setAttribute('value', names[0]);
    foil.state = 1;
    appendChild(foil);
  }

  /**
   * Add a foil (using an UndoableEdit)
   */
  void addUndoableFoil() {
    MatchFoil foil = new MatchFoil.fromRef(foilRef);
    List<String> names = getItemNames();
    if (names.length > 0)
      foil.setAttribute('value', names[0]);
    foil.state = 1;
    doc.insertNode(foil, new Position(this, offsetLength));
    page.moveCursorTo(new Position(foil, 0));
    page.updateAfterPathChange();
  }

  /**
   * Removes the given foil (called when the user click on the button).
   */
  void removeFoil(MatchFoil foil) {
    doc.doNewEdit(new UndoableEdit.removeNode(foil));
  }

  UndoableEdit updateFoilsAfterItemNameChangeEdit(String oldName, String newName) {
    UndoableEdit compound = null;
    for (MatchFoil foil in getFoils()) {
      if (foil.getAttribute('value') == oldName) {
        if (compound == null)
          compound = new UndoableEdit.compound(LCDStrings.get('item_name_change'));
        compound.addSubEdit(new UndoableEdit.changeAttribute(foil,
            new DaxeAttr('value', newName), updateDisplay:false));
      }
    }
    return compound;
  }

  UndoableEdit updateFoilsAfterItemRemovalEdit(String name) {
    UndoableEdit compound = null;
    for (MatchFoil foil in getFoils()) {
      if (foil.getAttribute('value') == name) {
        List<String> names = getItemNames();
        String newName = null;
        for (String itemName in names) {
          if (itemName != name) {
            newName = itemName;
            break;
          }
        }
        if (newName != null) {
          if (compound == null)
            compound = new UndoableEdit.compound(LCDStrings.get('item_name_change'));
          compound.addSubEdit(new UndoableEdit.changeAttribute(foil,
              new DaxeAttr('value', newName)));
        }
      }
    }
    return compound;
  }

}

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>