Skip to content
Snippets Groups Projects
Select Git revision
  • 53acfb9b7857a7cb6867b47a1abfe530f76e2aa6
  • renovate/django-split-settings-1.x
  • renovate/djangorestframework-3.x
  • main
  • 520-improve-trackmanager
  • 520-fix-scheduling
  • 520-akowner
  • 520-status
  • 520-message-resolved
  • 520-improve-scheduling-2
  • renovate/django-bootstrap5-24.x
  • 520-improve-submission
  • 520-improve-scheduling
  • 520-improve-wall
  • 520-fix-event-wizard-datepicker
  • 520-upgrades
  • renovate/tzdata-2023.x
  • renovate/django-5.x
  • renovate/fontawesomefree-6.x
  • renovate/sphinx-rtd-theme-2.x
  • renovate/sphinxcontrib-apidoc-0.x
21 results

apps.py

Blame
  • Forked from KIF / AKPlanning
    Source project has a limited visibility.
    • Benjamin Hättasch's avatar
      4fa76fdc
      Improve AKSubmission · 4fa76fdc
      Benjamin Hättasch authored
      Add docstrings
      Remove code-duplications for dispatching user selection on submission overview
      Remove code smells
      Remove unused admin.py
      Remove unused view in views
      4fa76fdc
      History
      Improve AKSubmission
      Benjamin Hättasch authored
      Add docstrings
      Remove code-duplications for dispatching user selection on submission overview
      Remove code smells
      Remove unused admin.py
      Remove unused view in views
    Code owners
    Assign users and groups as approvers for specific file changes. Learn more.
    domline.js 8.49 KiB
    'use strict';
    
    // THIS FILE IS ALSO AN APPJET MODULE: etherpad.collab.ace.domline
    // %APPJET%: import("etherpad.admin.plugins");
    /**
     * Copyright 2009 Google Inc.
     *
     * Licensed under the Apache License, Version 2.0 (the "License");
     * you may not use this file except in compliance with the License.
     * You may obtain a copy of the License at
     *
     *      http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS-IS" BASIS,
     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     * See the License for the specific language governing permissions and
     * limitations under the License.
     */
    
    // requires: top
    // requires: plugins
    // requires: undefined
    
    const Security = require('./security');
    const hooks = require('./pluginfw/hooks');
    const _ = require('./underscore');
    const lineAttributeMarker = require('./linestylefilter').lineAttributeMarker;
    const noop = () => {};
    
    
    const domline = {};
    
    domline.addToLineClass = (lineClass, cls) => {
      // an "empty span" at any point can be used to add classes to
      // the line, using line:className.  otherwise, we ignore
      // the span.
      cls.replace(/\S+/g, (c) => {
        if (c.indexOf('line:') === 0) {
          // add class to line
          lineClass = (lineClass ? `${lineClass} ` : '') + c.substring(5);
        }
      });
      return lineClass;
    };
    
    // if "document" is falsy we don't create a DOM node, just
    // an object with innerHTML and className
    domline.createDomLine = (nonEmpty, doesWrap, optBrowser, optDocument) => {
      const result = {
        node: null,
        appendSpan: noop,
        prepareForAdd: noop,
        notifyAdded: noop,
        clearSpans: noop,
        finishUpdate: noop,
        lineMarker: 0,
      };
    
      const document = optDocument;
    
      if (document) {
        result.node = document.createElement('div');
        // JAWS and NVDA screen reader compatibility. Only needed if in a real browser.
        result.node.setAttribute('aria-live', 'assertive');
      } else {
        result.node = {
          innerHTML: '',
          className: '',
        };
      }
    
      let html = [];
      let preHtml = '';
      let postHtml = '';
      let curHTML = null;
    
      const processSpaces = (s) => domline.processSpaces(s, doesWrap);
      const perTextNodeProcess = (doesWrap ? _.identity : processSpaces);
      const perHtmlLineProcess = (doesWrap ? processSpaces : _.identity);
      let lineClass = 'ace-line';
    
      result.appendSpan = (txt, cls) => {
        let processedMarker = false;
        // Handle lineAttributeMarker, if present
        if (cls.indexOf(lineAttributeMarker) >= 0) {
          let listType = /(?:^| )list:(\S+)/.exec(cls);
          const start = /(?:^| )start:(\S+)/.exec(cls);
    
          _.map(hooks.callAll('aceDomLinePreProcessLineAttributes', {
            domline,
            cls,
          }), (modifier) => {
            preHtml += modifier.preHtml;
            postHtml += modifier.postHtml;
            processedMarker |= modifier.processedMarker;
          });
          if (listType) {
            listType = listType[1];
            if (listType) {
              if (listType.indexOf('number') < 0) {
                preHtml += `<ul class="list-${Security.escapeHTMLAttribute(listType)}"><li>`;
                postHtml = `</li></ul>${postHtml}`;
              } else {
                if (start) { // is it a start of a list with more than one item in?
                  if (Number.parseInt(start[1]) === 1) { // if its the first one at this level?
                    // Add start class to DIV node
                    lineClass = `${lineClass} ` + `list-start-${listType}`;
                  }
                  preHtml +=
                    `<ol start=${start[1]} class="list-${Security.escapeHTMLAttribute(listType)}"><li>`;
                } else {
                  // Handles pasted contents into existing lists
                  preHtml += `<ol class="list-${Security.escapeHTMLAttribute(listType)}"><li>`;
                }
                postHtml += '</li></ol>';
              }
            }
            processedMarker = true;
          }
          _.map(hooks.callAll('aceDomLineProcessLineAttributes', {
            domline,
            cls,
          }), (modifier) => {
            preHtml += modifier.preHtml;
            postHtml += modifier.postHtml;
            processedMarker |= modifier.processedMarker;
          });
          if (processedMarker) {
            result.lineMarker += txt.length;
            return; // don't append any text
          }
        }
        let href = null;
        let simpleTags = null;
        if (cls.indexOf('url') >= 0) {
          cls = cls.replace(/(^| )url:(\S+)/g, (x0, space, url) => {
            href = url;
            return `${space}url`;
          });
        }
        if (cls.indexOf('tag') >= 0) {
          cls = cls.replace(/(^| )tag:(\S+)/g, (x0, space, tag) => {
            if (!simpleTags) simpleTags = [];
            simpleTags.push(tag.toLowerCase());
            return space + tag;
          });
        }
    
        let extraOpenTags = '';
        let extraCloseTags = '';
    
        _.map(hooks.callAll('aceCreateDomLine', {
          domline,
          cls,
        }), (modifier) => {
          cls = modifier.cls;
          extraOpenTags += modifier.extraOpenTags;
          extraCloseTags = modifier.extraCloseTags + extraCloseTags;
        });
    
        if ((!txt) && cls) {
          lineClass = domline.addToLineClass(lineClass, cls);
        } else if (txt) {
          if (href) {
            const urn_schemes = new RegExp('^(about|geo|mailto|tel):');
            // if the url doesn't include a protocol prefix, assume http
            if (!~href.indexOf('://') && !urn_schemes.test(href)) {
              href = `http://${href}`;
            }
            // Using rel="noreferrer" stops leaking the URL/location of the pad when
            // clicking links in the document.
            // Not all browsers understand this attribute, but it's part of the HTML5 standard.
            // https://html.spec.whatwg.org/multipage/links.html#link-type-noreferrer
            // Additionally, we do rel="noopener" to ensure a higher level of referrer security.
            // https://html.spec.whatwg.org/multipage/links.html#link-type-noopener
            // https://mathiasbynens.github.io/rel-noopener/
            // https://github.com/ether/etherpad-lite/pull/3636
            const escapedHref = Security.escapeHTMLAttribute(href);
            extraOpenTags = `${extraOpenTags}<a href="${escapedHref}" rel="noreferrer noopener">`;
            extraCloseTags = `</a>${extraCloseTags}`;
          }
          if (simpleTags) {
            simpleTags.sort();
            extraOpenTags = `${extraOpenTags}<${simpleTags.join('><')}>`;
            simpleTags.reverse();
            extraCloseTags = `</${simpleTags.join('></')}>${extraCloseTags}`;
          }
          html.push(
              '<span class="', Security.escapeHTMLAttribute(cls || ''),
              '">',
              extraOpenTags,
              perTextNodeProcess(Security.escapeHTML(txt)),
              extraCloseTags,
              '</span>');
        }
      };
      result.clearSpans = () => {
        html = [];
        lineClass = 'ace-line';
        result.lineMarker = 0;
      };
    
      const writeHTML = () => {
        let newHTML = perHtmlLineProcess(html.join(''));
        if (!newHTML) {
          if ((!document) || (!optBrowser)) {
            newHTML += '&nbsp;';
          } else {
            newHTML += '<br/>';
          }
        }
        if (nonEmpty) {
          newHTML = (preHtml || '') + newHTML + (postHtml || '');
        }
        html = preHtml = postHtml = ''; // free memory
        if (newHTML !== curHTML) {
          curHTML = newHTML;
          result.node.innerHTML = curHTML;
        }
        if (lineClass != null) result.node.className = lineClass;
    
        hooks.callAll('acePostWriteDomLineHTML', {
          node: result.node,
        });
      };
      result.prepareForAdd = writeHTML;
      result.finishUpdate = writeHTML;
      return result;
    };
    
    domline.processSpaces = (s, doesWrap) => {
      if (s.indexOf('<') < 0 && !doesWrap) {
        // short-cut
        return s.replace(/ /g, '&nbsp;');
      }
      const parts = [];
      s.replace(/<[^>]*>?| |[^ <]+/g, (m) => {
        parts.push(m);
      });
      if (doesWrap) {
        let endOfLine = true;
        let beforeSpace = false;
        // last space in a run is normal, others are nbsp,
        // end of line is nbsp
        for (let i = parts.length - 1; i >= 0; i--) {
          const p = parts[i];
          if (p === ' ') {
            if (endOfLine || beforeSpace) parts[i] = '&nbsp;';
            endOfLine = false;
            beforeSpace = true;
          } else if (p.charAt(0) !== '<') {
            endOfLine = false;
            beforeSpace = false;
          }
        }
        // beginning of line is nbsp
        for (let i = 0; i < parts.length; i++) {
          const p = parts[i];
          if (p === ' ') {
            parts[i] = '&nbsp;';
            break;
          } else if (p.charAt(0) !== '<') {
            break;
          }
        }
      } else {
        for (let i = 0; i < parts.length; i++) {
          const p = parts[i];
          if (p === ' ') {
            parts[i] = '&nbsp;';
          }
        }
      }
      return parts.join('');
    };
    
    exports.domline = domline;