File:  [LON-CAPA] / modules / damieng / graphical_editor / loncapa_daxe / web / lcd_insert_panel.dart
Revision 1.2: download - view: text, annotated - select for diffs
Thu Mar 30 19:53:39 2017 UTC (7 years, 2 months ago) by damieng
Branches: MAIN
CVS tags: HEAD
speed optimization

/*
  This file is part of LON-CAPA.

  LON-CAPA 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.

  LON-CAPA 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 LON-CAPA.  If not, see <http://www.gnu.org/licenses/>.
*/

part of loncapa_daxe;

/**
 * Left panel to insert elements.
 * This LON-CAPA version adds a filter
 */
class LCDInsertPanel extends InsertPanel {
  
  final List<String> HTMLElements = ['html', 'head', 'title', 'base', 'meta', 'link', 'style',
    'script', 'noscript', 'body', 'section', 'header', 'footer', 'article', 'aside',
    'nav', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'div', 'p', 'ul', 'ol', 'li', 'dl', 'dt',
    'dd', 'table', 'caption', 'thead', 'tfoot', 'tbody', 'tr', 'td', 'th', 'span', 'a',
    'em', 'strong', 'b', 'i', 'sup', 'sub', 'pre', 'code', 'kbd', 'samp', 'cite', 'q',
    'tt', 'ins', 'del', 'var', 'small', 'big', 'br', 'hr', 'address', 'blockquote',
    'bdo', 'ruby', 'rb', 'rp', 'rt', 'rtc', 'img', 'figure', 'figcaption', 'object',
    'param', 'embed', 'applet', 'video', 'source', 'audio', 'map', 'area', 'canvas',
    'form', 'label', 'input', 'select', 'optgroup', 'option', 'textarea', 'fieldset',
    'legend', 'button', 'iframe'];
  
  String selectedFilter;
  DaxeNode _parent;
  List<x.Element> _refs;
  List<x.Element> _validRefs;
  
  @override
  void update(DaxeNode parent, List<x.Element> refs, List<x.Element> validRefs) {
    if (!updateNeeded(parent, refs, validRefs))
      return;
    realUpdate(parent, refs, validRefs);
  }
  
  void realUpdate(DaxeNode parent, List<x.Element> refs1, List<x.Element> validRefs1) {
    Config cfg = doc.cfg;
    if (cfg == null)
      return;
    _parent = parent;
    _refs = refs1;
    _validRefs = validRefs1;
    h.Element oldDivInsert = h.document.getElementById('insert');
    h.DivElement divInsert = h.document.createElement('div');
    divInsert.id = 'insert';
    if (parent.nodeType == DaxeNode.ELEMENT_NODE && parent.ref != null) {
      divInsert.append(makeHelpButton(parent.ref));
      String name = cfg.elementName(parent.ref);
      h.SpanElement span = new h.SpanElement();
      span.appendText(cfg.menuTitle(name));
      divInsert.append(span);
      divInsert.append(new h.HRElement());
    }
    // Add the filter menu
    divInsert.appendText(LCDStrings.get('filter') + ' ');
    h.SelectElement select = new h.SelectElement();
    h.OptionElement option = new h.OptionElement();
    option.text = LCDStrings.get('all_elements');
    option.value = 'all_elements';
    if (selectedFilter == 'all_elements')
      option.selected = true;
    select.append(option);
    option = new h.OptionElement();
    option.text = LCDStrings.get('loncapa_elements');
    option.value = 'loncapa_elements';
    if (selectedFilter == 'loncapa_elements')
      option.selected = true;
    select.append(option);
    option = new h.OptionElement();
    option.text = LCDStrings.get('html_elements');
    option.value = 'html_elements';
    if (selectedFilter == 'html_elements')
      option.selected = true;
    select.append(option);
    option = new h.OptionElement();
    option.text = LCDStrings.get('block_elements');
    option.value = 'block_elements';
    if (selectedFilter == 'block_elements')
      option.selected = true;
    select.append(option);
    option = new h.OptionElement();
    option.text = LCDStrings.get('inline_elements');
    option.value = 'inline_elements';
    if (selectedFilter == 'inline_elements')
      option.selected = true;
    select.append(option);
    select.onChange.listen((h.Event event) => filter(select));
    divInsert.append(select);
    divInsert.append(new h.HRElement());
    // filter elements
    List<x.Element> refs = new List.from(refs1);
    List<x.Element> validRefs = new List.from(validRefs1);
    switch (selectedFilter) {
      case 'loncapa_elements':
        refs.removeWhere((x.Element ref) => HTMLElements.contains(doc.cfg.elementName(ref)));
        break;
      case 'html_elements':
        refs.retainWhere((x.Element ref) => HTMLElements.contains(doc.cfg.elementName(ref)));
        break;
      case 'block_elements':
        DaxeNode root = doc.getRootElement();
        x.Element hiddenp = cfg.findSubElement(root.ref, doc.hiddenParaRefs);
        refs.removeWhere((x.Element ref) => doc.cfg.isSubElement(hiddenp, ref));
        break;
      case 'inline_elements':
        DaxeNode root = doc.getRootElement();
        x.Element hiddenp = cfg.findSubElement(root.ref, doc.hiddenParaRefs);
        refs.retainWhere((x.Element ref) => doc.cfg.isSubElement(hiddenp, ref));
        break;
    }
    // Items already in the toolbar are not displayed if there are lots of elements to list.
    List<x.Element> toolbarRefs;
    if (refs.length > 15 && page.toolbar != null)
      toolbarRefs = page.toolbar.elementRefs();
    else
      toolbarRefs = null;
    for (x.Element ref in refs) {
      if (toolbarRefs != null && toolbarRefs.contains(ref))
        continue;
      if (doc.hiddenParaRefs != null && doc.hiddenParaRefs.contains(ref))
        continue;
      divInsert.append(makeHelpButton(ref));
      h.ButtonElement button = new h.ButtonElement();
      button.attributes['type'] = 'button';
      button.classes.add('insertb');
      String name = cfg.elementName(ref);
      button.value = name;
      button.text = cfg.menuTitle(name);
      if (!validRefs.contains(ref))
        button.disabled = true;
      button.onClick.listen((h.Event event) => insert(ref));
      button.onKeyDown.listen((h.KeyboardEvent event) {
        int keyCode = event.keyCode;
        if (keyCode == h.KeyCode.ENTER) {
          event.preventDefault();
          insert(ref);
        }
      });
      divInsert.append(button);
      divInsert.append(new h.BRElement());
    }
    oldDivInsert.replaceWith(divInsert);
  }
  
  void filter(h.SelectElement select) {
    selectedFilter = select.value;
    if (_parent != null)
      realUpdate(_parent, _refs, _validRefs);
  }
}

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