Merge branch 'MDL-57972-master' of git://github.com/ryanwyllie/moodle
This commit is contained in:
@@ -56,6 +56,7 @@ lib/amd/src/chartjs-lazy.js
|
||||
lib/maxmind/GeoIp2/
|
||||
lib/maxmind/MaxMind/
|
||||
lib/ltiprovider/
|
||||
lib/amd/src/truncate.js
|
||||
media/player/videojs/amd/src/video-lazy.js
|
||||
media/player/videojs/amd/src/Youtube-lazy.js
|
||||
media/player/videojs/videojs/
|
||||
|
||||
@@ -57,6 +57,7 @@ lib/amd/src/chartjs-lazy.js
|
||||
lib/maxmind/GeoIp2/
|
||||
lib/maxmind/MaxMind/
|
||||
lib/ltiprovider/
|
||||
lib/amd/src/truncate.js
|
||||
media/player/videojs/amd/src/video-lazy.js
|
||||
media/player/videojs/amd/src/Youtube-lazy.js
|
||||
media/player/videojs/videojs/
|
||||
|
||||
Vendored
+1
-1
File diff suppressed because one or more lines are too long
Vendored
+1
@@ -0,0 +1 @@
|
||||
define(["jquery"],function(a){var b=/(\s*\S+|\s)$/,c=/^(\S*)/,d=/\s/,e=function(a,b){if(null==this)throw TypeError();var c=String(a),d=c.length,e=b?Number(b):0;if(e!=e&&(e=0),e<=-1||e>=d)return"";e=0|e;var f,g=c.charCodeAt(e),h=e+1,i=1;return g>=55296&&g<=56319&&d>h&&(f=c.charCodeAt(h),f>=56320&&f<=57343&&(i=2)),i},f=function(a){for(var b=0,c=0;c<a.length;c+=e(a,c))b++;return b},g=function(a,b){if(!a.length)return 0;var c=0,d=0;do c+=e(a,c),d++;while(c<a.length&&d<b);return c};return a.truncate=function(b,c){return a("<div></div>").append(b).truncate(c).html()},a.fn.truncate=function(e){a.isNumeric(e)&&(e={length:e});var h=a.extend({},a.truncate.defaults,e);return this.each(function(){var e=a(this);h.noBreaks&&e.find("br").replaceWith(" ");var i=h.ellipsis.length,j=e.text(),k=f(j),l=k-h.length+i;if(!(k<h.length)){if(h.stripTags&&e.text(j),h.words&&l>0){var m=j.slice(0,g(j,h.length-i)+1),n=m.replace(b,""),o=f(n),p=!m.match(d);l=h.keepFirstWord&&0===o?k-f(c.exec(j)[0])-i:p&&0===o?k-h.length+i:k-o-1}l>k&&(l=k-h.length),l<0||!l&&!h.truncated||a.each(e.contents().get().reverse(),function(b,c){var d=a(c),e=d.text(),j=f(e);if(j<=l)return h.truncated=!0,l-=j,void d.remove();if(3===c.nodeType){var k=j-l;return k=k>=0?g(e,k):0,a(c.splitText(k)).replaceWith(h.ellipsis),!1}return d.truncate(a.extend(h,{length:j-l+i})),!1})}})},a.truncate.defaults={stripTags:!1,words:!1,keepFirstWord:!1,noBreaks:!1,length:1/0,ellipsis:"…"},{truncate:a.truncate}});
|
||||
@@ -29,14 +29,14 @@ define(['core/mustache',
|
||||
'core/str',
|
||||
'core/notification',
|
||||
'core/url',
|
||||
'core/log',
|
||||
'core/config',
|
||||
'core/localstorage',
|
||||
'core/event',
|
||||
'core/yui',
|
||||
'core/log'
|
||||
'core/log',
|
||||
'core/truncate'
|
||||
],
|
||||
function(mustache, $, ajax, str, notification, coreurl, log, config, storage, event, Y, Log) {
|
||||
function(mustache, $, ajax, str, notification, coreurl, config, storage, event, Y, Log, Truncate) {
|
||||
|
||||
// Module variables.
|
||||
/** @var {Number} uniqInstances Count of times this constructor has been called. */
|
||||
@@ -261,6 +261,33 @@ define(['core/mustache',
|
||||
return '"' + content + '"';
|
||||
};
|
||||
|
||||
/**
|
||||
* Shorten text helper to truncate text and append a trailing ellipsis.
|
||||
*
|
||||
* @method shortenTextHelper
|
||||
* @private
|
||||
* @param {object} context The current mustache context.
|
||||
* @param {string} sectionText The text to parse the arguments from.
|
||||
* @param {function} helper Used to render subsections of the text.
|
||||
* @return {string}
|
||||
*/
|
||||
Renderer.prototype.shortenTextHelper = function(context, sectionText, helper) {
|
||||
// Non-greedy split on comma to grab section text into the length and
|
||||
// text parts.
|
||||
var regex = /(.*?),(.*)/;
|
||||
var parts = sectionText.match(regex);
|
||||
// The length is the part matched in the first set of parethesis.
|
||||
var length = parts[1].trim();
|
||||
// The length is the part matched in the second set of parethesis.
|
||||
var text = parts[2].trim();
|
||||
var content = helper(text, context);
|
||||
return Truncate.truncate(content, {
|
||||
length: length,
|
||||
words: true,
|
||||
ellipsis: '...'
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Add some common helper functions to all context objects passed to templates.
|
||||
* These helpers match exactly the helpers available in php.
|
||||
@@ -287,6 +314,9 @@ define(['core/mustache',
|
||||
context.quote = function() {
|
||||
return this.quoteHelper.bind(this, context);
|
||||
}.bind(this);
|
||||
context.shortentext = function() {
|
||||
return this.shortenTextHelper.bind(this, context);
|
||||
}.bind(this);
|
||||
context.globals = {config: config};
|
||||
context.currentTheme = themeName;
|
||||
};
|
||||
|
||||
@@ -0,0 +1,219 @@
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle 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.
|
||||
//
|
||||
// Moodle 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 Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
/**
|
||||
* Description of import/upgrade into Moodle:
|
||||
* 1.) Download from https://github.com/pathable/truncate
|
||||
* 2.) Copy jquery.truncate.js into lib/amd/src/truncate.js
|
||||
* 3.) Edit truncate.js to return the $.truncate function as truncate
|
||||
* 4.) Apply Moodle changes from git commit 7172b33e241c4d42cff01f78bf8570408f43fdc2
|
||||
*/
|
||||
|
||||
/**
|
||||
* Module for text truncation.
|
||||
*
|
||||
* Implementation provided by Pathable (thanks!).
|
||||
* See: https://github.com/pathable/truncate
|
||||
*
|
||||
* @module core/truncate
|
||||
* @package core
|
||||
* @class truncate
|
||||
* @copyright 2017 Pathable
|
||||
* 2017 Mathias Bynens
|
||||
* 2017 Ryan Wyllie <[email protected]>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
define(['jquery'], function($) {
|
||||
|
||||
// Matches trailing non-space characters.
|
||||
var chop = /(\s*\S+|\s)$/;
|
||||
|
||||
// Matches the first word in the string.
|
||||
var start = /^(\S*)/;
|
||||
|
||||
// Matches any space characters.
|
||||
var space = /\s/;
|
||||
|
||||
// Special thanks to Mathias Bynens for the multi-byte char
|
||||
// implementation. Much love.
|
||||
// see: https://github.com/mathiasbynens/String.prototype.at/blob/master/at.js
|
||||
var charLengthAt = function(text, position) {
|
||||
if (this == null) {
|
||||
throw TypeError();
|
||||
}
|
||||
var string = String(text);
|
||||
var size = string.length;
|
||||
// `ToInteger`
|
||||
var index = position ? Number(position) : 0;
|
||||
if (index != index) { // better `isNaN`
|
||||
index = 0;
|
||||
}
|
||||
// Account for out-of-bounds indices
|
||||
// The odd lower bound is because the ToInteger operation is
|
||||
// going to round `n` to `0` for `-1 < n <= 0`.
|
||||
if (index <= -1 || index >= size) {
|
||||
return '';
|
||||
}
|
||||
// Second half of `ToInteger`
|
||||
index = index | 0;
|
||||
// Get the first code unit and code unit value
|
||||
var cuFirst = string.charCodeAt(index);
|
||||
var cuSecond;
|
||||
var nextIndex = index + 1;
|
||||
var len = 1;
|
||||
if ( // Check if it’s the start of a surrogate pair.
|
||||
cuFirst >= 0xD800 && cuFirst <= 0xDBFF && // high surrogate
|
||||
size > nextIndex // there is a next code unit
|
||||
) {
|
||||
cuSecond = string.charCodeAt(nextIndex);
|
||||
if (cuSecond >= 0xDC00 && cuSecond <= 0xDFFF) { // low surrogate
|
||||
len = 2;
|
||||
}
|
||||
}
|
||||
return len;
|
||||
};
|
||||
|
||||
var lengthMultiByte = function(text) {
|
||||
var count = 0;
|
||||
|
||||
for (var i = 0; i < text.length; i += charLengthAt(text, i)) {
|
||||
count++;
|
||||
}
|
||||
|
||||
return count;
|
||||
};
|
||||
|
||||
var getSliceLength = function(text, amount) {
|
||||
if (!text.length) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
var length = 0;
|
||||
var count = 0;
|
||||
|
||||
do {
|
||||
length += charLengthAt(text, length);
|
||||
count++;
|
||||
} while (length < text.length && count < amount);
|
||||
|
||||
return length;
|
||||
};
|
||||
|
||||
// Return a truncated html string. Delegates to $.fn.truncate.
|
||||
$.truncate = function(html, options) {
|
||||
return $('<div></div>').append(html).truncate(options).html();
|
||||
};
|
||||
|
||||
// Truncate the contents of an element in place.
|
||||
$.fn.truncate = function(options) {
|
||||
if ($.isNumeric(options)) options = {length: options};
|
||||
var o = $.extend({}, $.truncate.defaults, options);
|
||||
|
||||
return this.each(function() {
|
||||
var self = $(this);
|
||||
|
||||
if (o.noBreaks) self.find('br').replaceWith(' ');
|
||||
|
||||
var ellipsisLength = o.ellipsis.length;
|
||||
var text = self.text();
|
||||
var textLength = lengthMultiByte(text);
|
||||
var excess = textLength - o.length + ellipsisLength;
|
||||
|
||||
if (textLength < o.length) return;
|
||||
if (o.stripTags) self.text(text);
|
||||
|
||||
// Chop off any partial words if appropriate.
|
||||
if (o.words && excess > 0) {
|
||||
var sliced = text.slice(0, getSliceLength(text, o.length - ellipsisLength) + 1);
|
||||
var replaced = sliced.replace(chop, '');
|
||||
var truncated = lengthMultiByte(replaced);
|
||||
var oneWord = sliced.match(space) ? false : true;
|
||||
|
||||
if (o.keepFirstWord && truncated === 0) {
|
||||
excess = textLength - lengthMultiByte(start.exec(text)[0]) - ellipsisLength;
|
||||
} else if (oneWord && truncated === 0) {
|
||||
excess = textLength - o.length + ellipsisLength;
|
||||
} else {
|
||||
excess = textLength - truncated - 1;
|
||||
}
|
||||
}
|
||||
|
||||
// The requested length is larger than the text. No need for ellipsis.
|
||||
if (excess > textLength) {
|
||||
excess = textLength - o.length;
|
||||
}
|
||||
|
||||
if (excess < 0 || !excess && !o.truncated) return;
|
||||
|
||||
// Iterate over each child node in reverse, removing excess text.
|
||||
$.each(self.contents().get().reverse(), function(i, el) {
|
||||
var $el = $(el);
|
||||
var text = $el.text();
|
||||
var length = lengthMultiByte(text);
|
||||
|
||||
// If the text is longer than the excess, remove the node and continue.
|
||||
if (length <= excess) {
|
||||
o.truncated = true;
|
||||
excess -= length;
|
||||
$el.remove();
|
||||
return;
|
||||
}
|
||||
|
||||
// Remove the excess text and append the ellipsis.
|
||||
if (el.nodeType === 3) {
|
||||
var splitAmount = length - excess;
|
||||
splitAmount = splitAmount >= 0 ? getSliceLength(text, splitAmount) : 0;
|
||||
$(el.splitText(splitAmount)).replaceWith(o.ellipsis);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Recursively truncate child nodes.
|
||||
$el.truncate($.extend(o, {length: length - excess + ellipsisLength}));
|
||||
return false;
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
$.truncate.defaults = {
|
||||
|
||||
// Strip all html elements, leaving only plain text.
|
||||
stripTags: false,
|
||||
|
||||
// Only truncate at word boundaries.
|
||||
words: false,
|
||||
|
||||
// When 'words' is active, keeps the first word in the string
|
||||
// even if it's longer than a target length.
|
||||
keepFirstWord: false,
|
||||
|
||||
// Replace instances of <br> with a single space.
|
||||
noBreaks: false,
|
||||
|
||||
// The maximum length of the truncated html.
|
||||
length: Infinity,
|
||||
|
||||
// The character to use as the ellipsis. The word joiner (U+2060) can be
|
||||
// used to prevent a hanging ellipsis, but displays incorrectly in Chrome
|
||||
// on Windows 7.
|
||||
// http://code.google.com/p/chromium/issues/detail?id=68323
|
||||
//ellipsis: '\u2026' // '\u2060\u2026'
|
||||
ellipsis: '\u2026' // '\u2060\u2026'
|
||||
|
||||
};
|
||||
|
||||
return {
|
||||
truncate: $.truncate,
|
||||
};
|
||||
});
|
||||
@@ -0,0 +1,64 @@
|
||||
<?php
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle 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.
|
||||
//
|
||||
// Moodle 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 Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
/**
|
||||
* Mustache helper shorten text.
|
||||
*
|
||||
* @package core
|
||||
* @category output
|
||||
* @copyright 2017 Ryan Wyllie <[email protected]>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
namespace core\output;
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
use Mustache_LambdaHelper;
|
||||
use renderer_base;
|
||||
|
||||
/**
|
||||
* This class will call shorten_text with the section content.
|
||||
*
|
||||
* @copyright 2017 Ryan Wyllie <[email protected]>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class mustache_shorten_text_helper {
|
||||
|
||||
/**
|
||||
* Read a length and text component from the string.
|
||||
*
|
||||
* {{#shortentext}}50,Some test to shorten{{/shortentext}}
|
||||
*
|
||||
* Both args are required. The length must come first.
|
||||
*
|
||||
* @param string $args The text to parse for arguments.
|
||||
* @param Mustache_LambdaHelper $helper Used to render nested mustache variables.
|
||||
* @return string
|
||||
*/
|
||||
public function shorten($args, Mustache_LambdaHelper $helper) {
|
||||
// Split the text into an array of variables.
|
||||
list($length, $text) = explode(',', $args, 2);
|
||||
$length = trim($length);
|
||||
$text = trim($text);
|
||||
|
||||
// Allow mustache tags in the text.
|
||||
$text = $helper->render($text);
|
||||
|
||||
return shorten_text($text, $length);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -91,6 +91,7 @@ class renderer_base {
|
||||
$quotehelper = new \core\output\mustache_quote_helper();
|
||||
$jshelper = new \core\output\mustache_javascript_helper($this->page->requires);
|
||||
$pixhelper = new \core\output\mustache_pix_helper($this);
|
||||
$shortentexthelper = new \core\output\mustache_shorten_text_helper();
|
||||
|
||||
// We only expose the variables that are exposed to JS templates.
|
||||
$safeconfig = $this->page->requires->get_config_for_javascript($this->page, $this);
|
||||
@@ -99,7 +100,8 @@ class renderer_base {
|
||||
'str' => array($stringhelper, 'str'),
|
||||
'quote' => array($quotehelper, 'quote'),
|
||||
'js' => array($jshelper, 'help'),
|
||||
'pix' => array($pixhelper, 'pix'));
|
||||
'pix' => array($pixhelper, 'pix'),
|
||||
'shortentext' => array($shortentexthelper, 'shorten'));
|
||||
|
||||
$this->mustache = new Mustache_Engine(array(
|
||||
'cache' => $cachedir,
|
||||
|
||||
@@ -291,4 +291,10 @@
|
||||
<version>3.0.2</version>
|
||||
<licenseversion>2.0</licenseversion>
|
||||
</library>
|
||||
<library>
|
||||
<location>amd/src/truncate.js</location>
|
||||
<name>Truncate.js</name>
|
||||
<license>MIT</license>
|
||||
<version>0.0.1</version>
|
||||
</library>
|
||||
</libraries>
|
||||
|
||||
Reference in New Issue
Block a user