diff --git a/browser/Makefile.am b/browser/Makefile.am
index 4d08a8fef762a..1ff65b43396f2 100644
--- a/browser/Makefile.am
+++ b/browser/Makefile.am
@@ -235,19 +235,19 @@ COOL_JS_LST =\
src/app/DocEvents.ts \
src/app/GraphicSelectionMiddleware.ts \
src/app/SearchService.ts \
+ src/app/Rectangle.ts \
+ src/app/Util.ts \
+ src/app/LOUtil.ts \
src/Leaflet.js \
src/errormessages.js \
src/unocommands.js \
src/UNO/Key.js \
src/core/Log.js \
src/core/Util.js \
- src/core/LOUtil.js \
src/core/geometry.ts \
- src/core/Rectangle.ts \
src/core/Class.js \
src/core/Events.js \
src/core/Socket.js \
- src/core/Matrix.js \
src/core/Debug.js \
src/geometry/Point.ts \
src/geometry/Bounds.ts \
diff --git a/browser/mocha_tests/LOUtil.test.ts b/browser/mocha_tests/LOUtil.test.ts
new file mode 100644
index 0000000000000..6d5d9508b6506
--- /dev/null
+++ b/browser/mocha_tests/LOUtil.test.ts
@@ -0,0 +1,144 @@
+///
+///
+///
+///
+///
+///
+///
+///
+
+var assert = require('assert').strict;
+
+describe('LOUtil static class members', function () {
+
+ describe('stringToBounds()', function () {
+ it('parse from string with separaters and whitespaces', function () {
+ const bounds = LOUtil.stringToBounds('1, 2, \n3, \t4 ');
+ const expected = cool.Bounds.toBounds([[1, 2], [4, 6]])
+ assert.deepEqual(expected, bounds);
+ });
+
+ it('parse from string with more than 4 numbers', function () {
+ const bounds = LOUtil.stringToBounds('1, 2, 3, 4, 5 ');
+ const expected = cool.Bounds.toBounds([[1, 2], [4, 6]])
+ assert.deepEqual(expected, bounds);
+ });
+ });
+
+ describe('stringToRectangles()', function () {
+
+ it('parse one rectangle from string with separaters and whitespaces', function () {
+ const rectangles = LOUtil.stringToRectangles('1, 2, \n3, \t4 ');
+ const bottomLeft = cool.Point.toPoint(1, 6);
+ const bottomRight = cool.Point.toPoint(4, 6);
+ const topLeft = cool.Point.toPoint(1, 2);
+ const topRight = cool.Point.toPoint(4, 2);
+ const expected = [[bottomLeft, bottomRight, topLeft, topRight],]
+ assert.deepEqual(expected, rectangles);
+ });
+
+ it('parse two rectangles from string with separaters and whitespaces', function () {
+ const rectangles = LOUtil.stringToRectangles('1, 2, \n3, \t4 ; 101, 202, \t3, \n4; ');
+ const bottomLeft = cool.Point.toPoint(1, 6);
+ const bottomRight = cool.Point.toPoint(4, 6);
+ const topLeft = cool.Point.toPoint(1, 2);
+ const topRight = cool.Point.toPoint(4, 2);
+ const offset = cool.Point.toPoint(100, 200);
+ const first = [bottomLeft, bottomRight, topLeft, topRight];
+ const second: cool.Point[] = [];
+ for (let idx = 0; idx < 4; ++idx) {
+ second.push(first[idx].add(offset));
+ }
+ const expected = [first, second];
+ assert.deepEqual(expected, rectangles);
+ });
+ });
+
+ describe('findItemWithAttributeRecursive()', function () {
+ it('match at depth 0', function () {
+ const expected = LOUtilTestData.tree;
+ assert.deepEqual(expected, LOUtil.findItemWithAttributeRecursive(LOUtilTestData.tree, 'id', 'level0'));
+ });
+
+ it('match at depth 1', function () {
+ const expected = LOUtilTestData.tree.children[1];
+ assert.deepEqual(expected, LOUtil.findItemWithAttributeRecursive(LOUtilTestData.tree, 'id', 'level1_2'));
+ });
+
+ it('match at depth 2', function () {
+ const expected = LOUtilTestData.tree.children[0].children[0];
+ assert.deepEqual(expected, LOUtil.findItemWithAttributeRecursive(LOUtilTestData.tree, 'id', 'level2'));
+ });
+ it('match at depth 3', function () {
+ const expected = LOUtilTestData.tree.children[0].children[0].children[1];
+ assert.deepEqual(expected, LOUtil.findItemWithAttributeRecursive(LOUtilTestData.tree, 'id', 'level3'));
+ });
+
+ it('no match in empty tree', function () {
+ assert.deepEqual(null, LOUtil.findItemWithAttributeRecursive({}, 'id', 'level0'));
+ });
+
+ it('no match for value', function () {
+ assert.deepEqual(null, LOUtil.findItemWithAttributeRecursive(LOUtilTestData.tree, 'id', 'level100'));
+ });
+
+ it('no match for key', function () {
+ assert.deepEqual(null, LOUtil.findItemWithAttributeRecursive(LOUtilTestData.tree, 'somekey', 'level3'));
+ });
+ });
+
+
+ describe('findIndexInParentByAttribute()', function () {
+ it('empty tree no match', function () {
+ assert.equal(-1, LOUtil.findIndexInParentByAttribute({}, 'class', 'xyz'));
+ });
+
+ it('non empty tree no match', function () {
+ assert.equal(-1, LOUtil.findIndexInParentByAttribute(LOUtilTestData.shortTree, 'class', 'xyz'));
+ });
+
+ it('multiple matches; get first', function () {
+ assert.equal(2, LOUtil.findIndexInParentByAttribute(LOUtilTestData.shortTree, 'class', 'bac'));
+ });
+
+ it('unique match', function () {
+ assert.equal(2, LOUtil.findIndexInParentByAttribute(LOUtilTestData.shortTree, 'name', 'BAC'));
+ });
+ });
+
+ describe('_doRectanglesIntersect()', function () {
+
+ it('rectangle intersects with itself', function () {
+ assert.ok(LOUtil._doRectanglesIntersect([10, 20, 100, 200], [10, 20, 100, 200]));
+ });
+
+ it('A contains B, there is intersection', function () {
+ assert.ok(LOUtil._doRectanglesIntersect([10, 20, 100, 200], [11, 21, 90, 190]));
+ });
+
+ it('B contains A, there is intersection', function () {
+ assert.ok(LOUtil._doRectanglesIntersect([11, 21, 90, 190], [10, 20, 100, 200]));
+ });
+
+ it('A meets B tangentially (vertical)', function () {
+ assert.ok(LOUtil._doRectanglesIntersect([10, 20, 100, 200], [110, 20, 10, 200]));
+ });
+
+ it('A meets B tangentially (horizontal)', function () {
+ assert.ok(LOUtil._doRectanglesIntersect([10, 20, 100, 200], [10, 220, 100, 20]));
+ });
+
+ it('A meets B tangentially (single point)', function () {
+ assert.ok(LOUtil._doRectanglesIntersect([10, 20, 100, 200], [110, 220, 10, 20]));
+ });
+
+ it('disjoint (bug in the function)', function () {
+ assert.ok(LOUtil._doRectanglesIntersect([10, 20, 100, 200], [111, 221, 100, 200]));
+ });
+
+ it('disjoint (rectangles very far away)', function () {
+ assert.ok(!LOUtil._doRectanglesIntersect([10, 20, 10, 20], [400, 500, 10, 20]));
+ });
+ });
+
+});
diff --git a/browser/mocha_tests/Rectangle.test.ts b/browser/mocha_tests/Rectangle.test.ts
index 505bc4f1c6007..cd0b7f2bc9436 100644
--- a/browser/mocha_tests/Rectangle.test.ts
+++ b/browser/mocha_tests/Rectangle.test.ts
@@ -1,6 +1,6 @@
///
///
-///
+///
var assert = require('assert').strict;
@@ -350,4 +350,4 @@ describe('coordinate API tests', function () {
}); // coords.forEach
-}); // root describe
\ No newline at end of file
+}); // root describe
diff --git a/browser/mocha_tests/Util.test.ts b/browser/mocha_tests/Util.test.ts
new file mode 100644
index 0000000000000..bf0958a02db4d
--- /dev/null
+++ b/browser/mocha_tests/Util.test.ts
@@ -0,0 +1,215 @@
+///
+///
+///
+
+var assert = require('assert');
+
+describe('Util static members tests', function () {
+
+ describe('stamp()', function () {
+ const obj1 = { _leaflet_id: -1 };
+ const obj2 = { _leaflet_id: -1 };
+ let obj1Id = Util.stamp(obj1);
+ let obj2Id = Util.stamp(obj2);
+ it('first: id must be > 0', function() {
+ assert.ok(obj1Id > 0);
+ });
+
+ it('second: id must be > 0', function() {
+ assert.ok(obj2Id > 0);
+ });
+
+ it('first objects id must be less than id of second object', function() {
+ assert.ok(obj1Id < obj2Id);
+ });
+
+ it('first: id must not change', function () {
+ assert.equal(obj1Id, Util.stamp(obj1));
+ });
+
+ it('second: id must not change', function () {
+ assert.equal(obj2Id, Util.stamp(obj2));
+ });
+
+ });
+
+ describe('formatNum()', function() {
+ it('integer with no decimal places', function () {
+ assertFloat(Util.formatNum(5, 0), 5, 1e-5, '');
+ });
+
+ it('integer with 4 decimal places', function () {
+ assertFloat(Util.formatNum(5, 4), 5, 1e-5, '');
+ });
+
+ it('decimal with 1 decimal places no-round', function () {
+ assertFloat(Util.formatNum(5.30333333, 1), 5.3, 1e-5, '');
+ });
+
+ it('decimal with 4 decimal places no-round', function () {
+ assertFloat(Util.formatNum(5.30333333, 4), 5.3033, 1e-5, '');
+ });
+
+ it('decimal with 1 decimal places round', function () {
+ assertFloat(Util.formatNum(5.35333333, 1), 5.4, 1e-5, '');
+ });
+
+ it('decimal with 4 decimal places round', function () {
+ assertFloat(Util.formatNum(5.30335333, 4), 5.3034, 1e-5, '');
+ });
+ });
+
+ describe('trimStart()', function () {
+ it('whole string is prefix', function () {
+ assert.strictEqual(Util.trimStart('ABC', 'ABC'), '');
+ });
+
+ it('whole string shorter than prefix', function () {
+ assert.strictEqual(Util.trimStart('ABC', 'ABCD'), 'ABC');
+ });
+
+ it('No prefix', function () {
+ assert.strictEqual(Util.trimStart('XYZ', 'ABCD'), 'XYZ');
+ });
+
+ it('Multi prefix', function () {
+ assert.strictEqual(Util.trimStart('ABCDABCDXYZ', 'ABCD'), 'ABCDXYZ');
+ });
+ });
+
+ describe('trimEnd()', function () {
+ it('whole string is suffix', function () {
+ assert.strictEqual(Util.trimEnd('ABC', 'ABC'), '');
+ });
+
+ it('whole string shorter than suffix', function () {
+ assert.strictEqual(Util.trimEnd('ABC', 'ABCD'), 'ABC');
+ });
+
+ it('No suffix', function () {
+ assert.strictEqual(Util.trimEnd('XYZ', 'ABCD'), 'XYZ');
+ });
+
+ it('Multi suffix', function () {
+ assert.strictEqual(Util.trimEnd('XYZABCDABCD', 'ABCD'), 'XYZABCD');
+ });
+ });
+
+ describe('trim()', function () {
+ it('trim() with no prefix or suffix argument', function () {
+ assert.strictEqual(Util.trim('\t \tCONTENT \t\t \t'), 'CONTENT');
+ });
+
+ it('whole string is prefix', function () {
+ assert.strictEqual(Util.trim('ABC', 'ABC'), '');
+ });
+
+ it('whole string shorter than prefix', function () {
+ assert.strictEqual(Util.trim('ABC', 'ABCD'), 'ABC');
+ });
+
+ it('whole string is suffix', function () {
+ assert.strictEqual(Util.trim('ABC', ' ', 'ABC'), '');
+ });
+
+ it('whole string shorter than suffix', function () {
+ assert.strictEqual(Util.trim('ABC', '', 'ABCD'), 'ABC');
+ });
+
+ it('No prefix', function () {
+ assert.strictEqual(Util.trim('XYZ', 'ABCD'), 'XYZ');
+ });
+
+ it('No suffix', function () {
+ assert.strictEqual(Util.trim('XYZ', '', 'ABCD'), 'XYZ');
+ });
+
+ it('Multi prefix and suffix', function () {
+ assert.strictEqual(Util.trim('ABCDABCDXYZABCDABCD', 'ABCD', 'ABCD'), 'ABCDXYZABCD');
+ });
+
+ it('Overlapping prefix and suffix', function () {
+ assert.strictEqual(Util.trim('ABCDAB', 'ABCD', 'CDAB'), 'AB');
+ });
+ });
+
+ describe('splitWords()', function () {
+ it('split empty string', function () {
+ assert.deepEqual(Util.splitWords(''), ['']);
+ });
+
+ it('split string with white spaces', function () {
+ assert.deepEqual(Util.splitWords(' \t \t\t '), ['']);
+ });
+
+ it('split string with single word', function () {
+ assert.deepEqual(Util.splitWords('ABC'), ['ABC']);
+ });
+
+ it('split string with single word surrounded by multi white-spaces', function () {
+ assert.deepEqual(Util.splitWords(' \t \t \t\t ABC\t \t\t \t'), ['ABC']);
+ });
+
+ it('split string with two words', function () {
+ assert.deepEqual(Util.splitWords(' \t \t \t\t ABC\t \t\t \tXYZ \t\t \t'), ['ABC', 'XYZ']);
+ });
+ });
+
+ describe('round()', function() {
+ it('integer with no decimal places', function () {
+ assertFloat(Util.round(5), 5, 1e-5, '');
+ });
+
+ it('integer with 4 decimal places', function () {
+ assertFloat(Util.round(5, 1e-4), 5, 1e-5, '');
+ });
+
+ it('decimal with 1 decimal places no-round', function () {
+ assertFloat(Util.round(5.30333333, 0.1), 5.3, 1e-5, '');
+ });
+
+ it('decimal with 4 decimal places no-round', function () {
+ assertFloat(Util.round(5.30333333, 0.0001), 5.3033, 1e-5, '');
+ });
+
+ it('decimal with 1 decimal places round', function () {
+ assertFloat(Util.round(5.35333333, 0.1), 5.4, 1e-5, '');
+ });
+
+ it('decimal with 4 decimal places round', function () {
+ assertFloat(Util.round(5.30335333, 0.0001), 5.3034, 1e-5, '');
+ });
+ });
+
+ describe('template()', function () {
+ it('empty string', function () {
+ assert.strictEqual(Util.template('', {}), '');
+ });
+
+ it('no substitutions', function () {
+ assert.strictEqual(Util.template('cool apps', {'cool': 32}), 'cool apps');
+ });
+
+ it('one key one substitution', function () {
+ assert.strictEqual(Util.template('cool { app } abcd', {'cool': 32, 'app': 'calc'}), 'cool calc abcd');
+ });
+
+ it('one key two substitutions', function () {
+ assert.strictEqual(Util.template('A {app } cool { app} abcd', {'cool': 32, 'app': 'calc'}), 'A calc cool calc abcd');
+ });
+
+ it('two keys multiple substitutions', function () {
+ assert.strictEqual(Util.template('A) { app1}, B) {app2 }, C) { app2}, D) { app1 } ', {'cool': 32, 'app': 'calc', 'app1': 'draw', 'app2': 'impress'}), 'A) draw, B) impress, C) impress, D) draw ');
+ });
+
+ it('key function', function () {
+ assert.strictEqual(Util.template('{fkey }, { key }', {
+ 'key': '1234',
+ 'fkey': function(data: any) {
+ return data['key'] + '_999';
+ },
+ }), '1234_999, 1234');
+ });
+ });
+
+});
diff --git a/browser/mocha_tests/data/LOUtilTestData.ts b/browser/mocha_tests/data/LOUtilTestData.ts
new file mode 100644
index 0000000000000..59d74d92cae6d
--- /dev/null
+++ b/browser/mocha_tests/data/LOUtilTestData.ts
@@ -0,0 +1,44 @@
+class LOUtilTestData {
+ public static tree = {
+ 'id': 'level0',
+ 'children': [
+ {
+ 'id': 'level1_1',
+ 'children': [
+ {
+ 'id': 'level2',
+ 'children': [
+ {
+ 'id': 'level3_0',
+ 'data': 4321,
+ },
+ {
+ 'id': 'level3',
+ 'children': [
+ {
+ 'id': 'level4',
+ 'data': 1234,
+ },
+ ],
+ },
+ ],
+ },
+ ],
+ },
+ {
+ 'id': 'level1_2',
+ },
+ ],
+ };
+
+ public static shortTree = {
+ id: 'level0',
+ children: [
+ { 'class': 'abc', 'name': 'ABC', },
+ { 'class': 'abc', 'name': 'ABC1', },
+ { 'class': 'bac', 'name': 'BAC', },
+ { 'class': 'bac', 'name': 'BAC1', },
+ { 'class': 'cab', 'name': 'CAB', },
+ ],
+ };
+}
diff --git a/browser/src/app/LOUtil.ts b/browser/src/app/LOUtil.ts
new file mode 100644
index 0000000000000..d0005fad06bd3
--- /dev/null
+++ b/browser/src/app/LOUtil.ts
@@ -0,0 +1,460 @@
+/* -*- js-indent-level: 8 -*- */
+/* global app */
+/*
+ * Copyright the Collabora Online contributors.
+ *
+ * SPDX-License-Identifier: MPL-2.0
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+interface DOMObjectLike {
+ [index: string]: any;
+ children?: DOMObjectLike[];
+}
+
+interface RectangleLike {
+ top: number;
+ left: number;
+ bottom: number;
+ right: number;
+}
+
+// LOUtil contains various LO related utility functions used
+// throughout the code.
+
+class LOUtil {
+ // Based on core.git's colordata.hxx: COL_AUTHOR1_DARK...COL_AUTHOR9_DARK
+ // consisting of arrays of RGB values
+ // Maybe move the color logic to separate file when it becomes complex
+ public static darkColors = [
+ [198, 146, 0],
+ [6, 70, 162],
+ [87, 157, 28],
+ [105, 43, 157],
+ [197, 0, 11],
+ [0, 128, 128],
+ [140, 132, 0],
+ [53, 85, 107],
+ [209, 118, 0],
+ ];
+
+ public static onRemoveHTMLElement(
+ element: Element,
+ onDetachCallback: () => void,
+ ) {
+ const observer = new MutationObserver(function () {
+ function isDetached(el: Element) {
+ return !el.closest('html');
+ }
+
+ if (isDetached(element)) {
+ onDetachCallback();
+ observer.disconnect();
+ }
+ });
+
+ observer.observe(document, {
+ childList: true,
+ subtree: true,
+ });
+ }
+
+ public static startSpinner(
+ spinnerCanvas: HTMLCanvasElement,
+ spinnerSpeed: number,
+ ): NodeJS.Timer {
+ spinnerCanvas.width = 50;
+ spinnerCanvas.height = 50;
+
+ const context = spinnerCanvas.getContext('2d');
+ context.lineWidth = 8;
+ context.strokeStyle = 'grey';
+ const x = spinnerCanvas.width / 2;
+ const y = spinnerCanvas.height / 2;
+ const radius = y - context.lineWidth / 2;
+ const spinnerInterval = setInterval(function () {
+ context.clearRect(0, 0, x * 2, y * 2);
+ // Move to center
+ context.translate(x, y);
+ context.rotate((spinnerSpeed * Math.PI) / 180);
+ context.translate(-x, -y);
+ context.beginPath();
+ context.arc(x, y, radius, 0, Math.PI * 1.3);
+ context.stroke();
+ }, 30);
+
+ return spinnerInterval;
+ }
+
+ public static getViewIdColor(viewId: number): number {
+ const color = LOUtil.darkColors[(viewId + 1) % LOUtil.darkColors.length];
+ return color[2] | (color[1] << 8) | (color[0] << 16);
+ }
+
+ public static rgbToHex(color: number) {
+ return '#' + ('000000' + color.toString(16)).slice(-6);
+ }
+
+ public static stringToBounds(bounds: string): cool.Bounds {
+ const numbers = bounds.match(/\d+/g);
+ const topLeft = cool.Point.toPoint(
+ parseInt(numbers[0]),
+ parseInt(numbers[1]),
+ );
+ const bottomRight = topLeft.add(
+ L.point(parseInt(numbers[2]), parseInt(numbers[3])),
+ );
+ return cool.Bounds.toBounds(topLeft, bottomRight);
+ }
+
+ public static stringToRectangles(strRect: string): cool.Point[][] {
+ const matches = strRect.match(/\d+/g);
+ const rectangles: cool.Point[][] = [];
+ if (matches !== null) {
+ for (let itMatch = 0; itMatch < matches.length; itMatch += 4) {
+ const topLeft = cool.Point.toPoint(
+ parseInt(matches[itMatch]),
+ parseInt(matches[itMatch + 1]),
+ );
+ const size = cool.Point.toPoint(
+ parseInt(matches[itMatch + 2]),
+ parseInt(matches[itMatch + 3]),
+ );
+ const topRight = topLeft.add(L.point(size.x, 0));
+ const bottomLeft = topLeft.add(L.point(0, size.y));
+ const bottomRight = topLeft.add(size);
+ rectangles.push([bottomLeft, bottomRight, topLeft, topRight]);
+ }
+ }
+ return rectangles;
+ }
+
+ // Some items will only be present in dark mode so we will not check errors
+ // for those in other mode.
+ public static onlydarkModeItems: string[] = ['invertbackground'];
+
+ // Common images used in all modes, so the default one will be used.
+ public static commonItems: string[] = ['serverauditok', 'serverauditerror'];
+
+ // Helper function to strip '.svg' suffix and 'lc_' prefix.
+ public static stripName(name: string): string {
+ // Remove the '.svg' suffix.
+ var strippedName = name.replace(/\.svg$/, '');
+
+ // Remove the 'lc_' prefix if it exists.
+ if (strippedName.startsWith('lc_')) {
+ strippedName = strippedName.substring(3);
+ }
+
+ return strippedName;
+ }
+
+ public static isDarkModeItem(name: string): boolean {
+ const strippedName = LOUtil.stripName(name);
+
+ // Check if the stripped name is in the onlydarkModeItems array.
+ return LOUtil.onlydarkModeItems.includes(strippedName);
+ }
+
+ public static isCommonForAllMode(name: string): boolean {
+ const strippedName = LOUtil.stripName(name);
+
+ // Check if the stripped name is in the commonItems array.
+ return LOUtil.commonItems.includes(strippedName);
+ }
+
+ /// unwind things to get a good absolute URL.
+ public static getURL(path: string): string {
+ if (path === '') return '';
+ const customWindow = window as any;
+ if (customWindow.host === '' && customWindow.serviceRoot === '')
+ return path; // mobile app
+
+ let url = customWindow.makeHttpUrl('/browser/' + customWindow.versionPath);
+ if (path.substr(0, 1) !== '/') url += '/';
+
+ url += path;
+ return url;
+ }
+
+ public static setImage(img: HTMLImageElement, name: string, map: any): void {
+ const setupIcon = function () {
+ img.src = LOUtil.getImageURL(name);
+ LOUtil.checkIfImageExists(img);
+ };
+ setupIcon();
+
+ map.on('themechanged', setupIcon);
+ }
+
+ public static setUserImage(
+ img: HTMLImageElement,
+ map: any,
+ viewId: number,
+ ): void {
+ // set avatar image if it exist in user extract info.
+ const defaultImage = LOUtil.getImageURL('user.svg');
+ const viewInfo = map._viewInfo[viewId];
+ if (
+ viewInfo !== undefined &&
+ viewInfo.userextrainfo !== undefined &&
+ viewInfo.userextrainfo.avatar !== undefined
+ ) {
+ // set user avatar.
+ img.src = viewInfo.userextrainfo.avatar;
+ // Track if error event is already bound to this image.
+ img.addEventListener(
+ 'error',
+ function () {
+ img.src = defaultImage;
+ LOUtil.checkIfImageExists(img, true);
+ },
+ { once: true },
+ );
+ return;
+ }
+ img.src = defaultImage;
+ LOUtil.checkIfImageExists(img, true);
+ }
+
+ public static getImageURL(imgName: string) {
+ let defaultImageURL = LOUtil.getURL('images/' + imgName);
+
+ // Check if the image name is in the commonItems list and return the normal image path
+ if (LOUtil.isCommonForAllMode(imgName)) {
+ return defaultImageURL;
+ }
+
+ if ((window as any).prefs.getBoolean('darkTheme')) {
+ return LOUtil.getURL('images/dark/' + imgName);
+ }
+
+ const dummyEmptyImg =
+ 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNkYAAAAAYAAjCB0C8AAAAASUVORK5CYII=';
+ defaultImageURL = LOUtil.isDarkModeItem(imgName)
+ ? dummyEmptyImg
+ : defaultImageURL;
+ return defaultImageURL;
+ }
+
+ public static checkIfImageExists(
+ imageElement: HTMLImageElement,
+ imageIsLayoutCritical?: boolean,
+ ): void {
+ imageElement.addEventListener('error', function (e: any) {
+ if (e.loUtilProcessed) {
+ return;
+ }
+
+ if (
+ imageElement.src &&
+ imageElement.src.includes('/images/branding/dark/')
+ ) {
+ imageElement.src = imageElement.src.replace(
+ '/images/branding/dark/',
+ '/images/dark/',
+ );
+ e.loUtilProcessed = true;
+ return;
+ }
+ if (
+ imageElement.src &&
+ (imageElement.src.includes('/images/dark/') ||
+ imageElement.src.includes('/images/branding/'))
+ ) {
+ imageElement.src = imageElement.src.replace(
+ '/images/dark/',
+ '/images/',
+ );
+ imageElement.src = imageElement.src.replace(
+ '/images/branding/',
+ '/images/',
+ );
+ e.loUtilProcessed = true;
+ return;
+ }
+
+ if (imageIsLayoutCritical) {
+ imageElement.src =
+ 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNkYAAAAAYAAjCB0C8AAAAASUVORK5CYII=';
+ // We cannot set visibility: hidden because that would hide
+ // other attributes of the image, e.g. its border.
+ e.loUtilProcessed = true;
+ return;
+ }
+
+ imageElement.style.display = 'none';
+ e.loUtilProcessed = true;
+ });
+ }
+
+ /// oldFileName = Example.odt, suffix = new
+ /// returns: Example_new.odt
+ public static generateNewFileName(
+ oldFileName: string,
+ suffix: string,
+ ): string {
+ const idx = oldFileName.lastIndexOf('.');
+ return oldFileName.substring(0, idx) + suffix + oldFileName.substring(idx);
+ }
+
+ public static commandWithoutIcon: string[] = [
+ 'InsertPageHeader',
+ 'InsertPageFooter',
+ 'FLD_COL_NUMBER',
+ 'MTR_FLD_COL_SPACING',
+ 'rows',
+ 'cols',
+ 'None',
+ ];
+
+ public static existsIconForCommand(
+ command: string,
+ docType: string,
+ ): boolean {
+ const commandName = command.startsWith('.uno:')
+ ? command.substring('.uno:'.length)
+ : command;
+ const res = !LOUtil.commandWithoutIcon.find(function (el: string) {
+ return el.startsWith(commandName);
+ });
+ if (commandName.indexOf('?') !== -1) {
+ if (
+ commandName.indexOf('SpellCheckIgnore') !== -1 ||
+ commandName.indexOf('SpellCheckIgnoreAll') !== -1
+ )
+ return true;
+
+ if (
+ (docType === 'spreadsheet' || docType === 'presentation') &&
+ commandName.indexOf('LanguageStatus') !== -1
+ )
+ return true;
+
+ if (
+ commandName ===
+ 'LanguageStatus?Language:string=Current_LANGUAGE_NONE' ||
+ commandName ===
+ 'LanguageStatus?Language:string=Current_RESET_LANGUAGES' ||
+ commandName ===
+ 'LanguageStatus?Language:string=Paragraph_LANGUAGE_NONE' ||
+ commandName ===
+ 'LanguageStatus?Language:string=Paragraph_RESET_LANGUAGES'
+ )
+ return true;
+
+ return false;
+ }
+ return res;
+ }
+
+ /// Searching in JSON trees for data with a given field.
+ public static findItemWithAttributeRecursive(
+ node: DOMObjectLike,
+ idName: string,
+ idValue: any,
+ ): DOMObjectLike | null {
+ let found: DOMObjectLike | null = null;
+ if (node[idName] === idValue) return node;
+ if (node.children) {
+ for (var i = 0; !found && i < node.children.length; i++)
+ found = LOUtil.findItemWithAttributeRecursive(
+ node.children[i],
+ idName,
+ idValue,
+ );
+ }
+ return found;
+ }
+
+ /// Searching in JSON trees for an identifier and return the index in parent.
+ public static findIndexInParentByAttribute(
+ node: DOMObjectLike,
+ idName: string,
+ idValue: any,
+ ): number {
+ if (node.children) {
+ for (var i = 0; i < node.children.length; i++)
+ if (node.children[i][idName] === idValue) return i;
+ }
+ return -1;
+ }
+
+ public static _doRectanglesIntersect(
+ rectangle1: number[],
+ rectangle2: number[],
+ ): boolean {
+ // Format: (x, y, w, h).
+ // Don't use equality in comparison, that's not an intersection.
+ if (
+ Math.abs(
+ rectangle1[0] +
+ rectangle1[2] * 0.5 -
+ (rectangle2[0] + rectangle2[2] * 0.5),
+ ) <
+ rectangle1[2] + rectangle2[2]
+ ) {
+ if (
+ Math.abs(
+ rectangle1[1] +
+ rectangle1[3] * 0.5 -
+ (rectangle2[1] + rectangle2[3] * 0.5),
+ ) <
+ rectangle1[3] + rectangle2[3]
+ )
+ return true;
+ else return false;
+ } else return false;
+ }
+
+ // Returns the intersecting area of 2 rectangles. Rectangle format: (x, y, w, h). Return format is the same or null.
+ public static _getIntersectionRectangle(
+ rectangle1: number[],
+ rectangle2: number[],
+ ): number[] | null {
+ if (this._doRectanglesIntersect(rectangle1, rectangle2)) {
+ var x = rectangle1[0] > rectangle2[0] ? rectangle1[0] : rectangle2[0];
+ var y = rectangle1[1] > rectangle2[1] ? rectangle1[1] : rectangle2[1];
+ var w =
+ rectangle1[0] + rectangle1[2] < rectangle2[0] + rectangle2[2]
+ ? rectangle1[0] + rectangle1[2] - x
+ : rectangle2[0] + rectangle2[2] - x;
+ var h =
+ rectangle1[1] + rectangle1[3] < rectangle2[1] + rectangle2[3]
+ ? rectangle1[1] + rectangle1[3] - y
+ : rectangle2[1] + rectangle2[3] - y;
+
+ return [x, y, w, h];
+ } else return null;
+ }
+
+ public static getFileExtension(map: any): string {
+ const filename: string = map['wopi'].BaseFileName;
+ return filename.substring(filename.lastIndexOf('.') + 1);
+ }
+
+ public static isFileODF(map: any): boolean {
+ var ext = LOUtil.getFileExtension(map);
+ return ext === 'odt' || ext === 'ods' || ext === 'odp' || ext == 'odg';
+ }
+
+ public static containsDOMRect(
+ viewRect: RectangleLike,
+ rect: RectangleLike,
+ ): boolean {
+ return (
+ rect.top >= viewRect.top &&
+ rect.right <= viewRect.right &&
+ rect.bottom <= viewRect.bottom &&
+ rect.left >= viewRect.left
+ );
+ }
+
+ public static Rectangle = cool.Rectangle;
+ public static createRectangle = cool.createRectangle;
+}
+
+app.LOUtil = LOUtil;
diff --git a/browser/src/app/Rectangle.ts b/browser/src/app/Rectangle.ts
new file mode 100644
index 0000000000000..0fec8a6c44954
--- /dev/null
+++ b/browser/src/app/Rectangle.ts
@@ -0,0 +1,261 @@
+/* -*- js-indent-level: 8 -*- */
+/*
+ * Copyright the Collabora Online contributors.
+ *
+ * SPDX-License-Identifier: MPL-2.0
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+namespace cool {
+ /**
+ * Represents a rectangle object which works with core pixels.
+ * x1 and y1 should always <= x2 and y2. In other words width >= 0 && height >= 0 is a precondition.
+ * This class doesn't check for above conditions. There is a isValid function for use when needed.
+ */
+ export class Rectangle {
+ private x1: number;
+ private y1: number;
+ private width: number;
+ private height: number;
+
+ constructor(x: number, y: number, width: number, height: number) {
+ this.x1 = x;
+ this.y1 = y;
+ this.width = width;
+ this.height = height;
+ }
+
+ // convenience private getters
+
+ private get x2(): number {
+ return this.x1 + this.width;
+ }
+
+ private get y2(): number {
+ return this.y1 + this.height;
+ }
+
+ private get area(): number {
+ return this.width * this.height;
+ }
+
+ // Rounded coordinates private getters
+
+ private get rx1(): number {
+ return Math.round(this.x1);
+ }
+
+ private get ry1(): number {
+ return Math.round(this.y1);
+ }
+
+ private get rx2(): number {
+ return Math.round(this.x2);
+ }
+
+ private get ry2(): number {
+ return Math.round(this.y2);
+ }
+
+ private get rwidth(): number {
+ return this.rx2 - this.rx1;
+ }
+
+ private get rheight(): number {
+ return this.ry2 - this.ry1;
+ }
+
+ private get rarea(): number {
+ return this.rwidth * this.rheight;
+ }
+
+ public isValid(): boolean {
+ if (this.x1 <= this.x2 && this.y1 <= this.y2) return true;
+ return false;
+ }
+
+ public clone(): Rectangle {
+ return new Rectangle(this.x1, this.x2, this.width, this.height);
+ }
+
+ public containsPoint(x: number, y: number): boolean {
+ if (x >= this.x1 && x <= this.x2 && y >= this.y1 && y <= this.y2)
+ return true;
+
+ return false;
+ }
+
+ public containsPixel(px: number, py: number): boolean {
+ if (px >= this.rx1 && px <= this.rx2 && py >= this.ry1 && py <= this.ry2)
+ return true;
+
+ return false;
+ }
+
+ public containsXOrdinate(ox: number): boolean {
+ if (ox >= this.x1 && ox <= this.x2) return true;
+
+ return false;
+ }
+
+ public containsYOrdinate(oy: number): boolean {
+ if (oy >= this.y1 && oy <= this.y2) return true;
+
+ return false;
+ }
+
+ public containsPixelOrdinateX(ox: number): boolean {
+ if (ox >= this.rx1 && ox <= this.rx2) return true;
+
+ return false;
+ }
+
+ public containsPixelOrdinateY(oy: number): boolean {
+ if (oy >= this.ry1 && oy <= this.ry2) return true;
+
+ return false;
+ }
+
+ /// Sets x1 of the rectangle without changing x2.
+ public setX1(x1: number): void {
+ this.width += this.x1 - x1;
+ this.x1 = x1;
+ }
+
+ /// Sets x2 of the rectangle without changing x1.
+ public setX2(x2: number): void {
+ this.width = x2 - this.x1;
+ }
+
+ /// Sets y1 of the rectangle without changing y2.
+ public setY1(y1: number): void {
+ this.height += this.y1 - y1;
+ this.y1 = y1;
+ }
+
+ /// Sets y2 of the rectangle without changing y1.
+ public setY2(y2: number): void {
+ this.height = y2 - this.y1;
+ }
+
+ /// Sets width keeping x1 constant.
+ public setWidth(width: number): void {
+ this.width = width;
+ }
+
+ /// Sets height keeping y1 constant.
+ public setHeight(height: number): void {
+ this.height = height;
+ }
+
+ /// Sets area by either keeping height or width as constant.
+ public setArea(area: number, preserveHeight: boolean): void {
+ if (!preserveHeight) {
+ //preserve width
+ const height = area / this.width;
+ this.setHeight(height);
+ } else {
+ // preserve height
+ const width = area / this.height;
+ this.setWidth(width);
+ }
+ }
+
+ /// Moves the whole rectangle by (dx, dy) by preserving width and height.
+ public moveBy(dx: number, dy: number): void {
+ this.x1 += dx;
+ this.y1 += dy;
+ }
+
+ /**
+ * Moves the rectangle to (x, y) as its new x1, y1 without changing
+ * its size.
+ */
+ public moveTo(x: number, y: number): void {
+ this.x1 = x;
+ this.y1 = y;
+ }
+
+ // TODO: Following methods could be replaced with js getters
+ // but we need to change their users to access getters.
+
+ public getX1(): number {
+ return this.x1;
+ }
+
+ public getX2(): number {
+ return this.x2;
+ }
+
+ public getY1(): number {
+ return this.y1;
+ }
+
+ public getY2(): number {
+ return this.y2;
+ }
+
+ public getWidth(): number {
+ return this.width;
+ }
+
+ public getHeight(): number {
+ return this.height;
+ }
+
+ public getArea(): number {
+ return this.area;
+ }
+
+ public getCenter(): number[] {
+ return [(this.x2 + this.x1) / 2, (this.y2 + this.y1) / 2];
+ }
+
+ public getPxX1(): number {
+ return this.rx1;
+ }
+
+ public getPxX2(): number {
+ return this.rx2;
+ }
+
+ public getPxY1(): number {
+ return this.ry1;
+ }
+
+ public getPxY2(): number {
+ return this.ry2;
+ }
+
+ public getPxWidth(): number {
+ return this.rwidth;
+ }
+
+ public getPxHeight(): number {
+ return this.rheight;
+ }
+
+ public getPxArea(): number {
+ return this.rarea;
+ }
+
+ public getPxCenter(): number[] {
+ return [
+ Math.round((this.rx2 + this.rx1) / 2),
+ Math.round((this.ry2 + this.ry1) / 2),
+ ];
+ }
+ }
+
+ export function createRectangle(
+ x: number,
+ y: number,
+ width: number,
+ height: number,
+ ): Rectangle {
+ return new Rectangle(x, y, width, height);
+ }
+}
diff --git a/browser/src/app/Util.ts b/browser/src/app/Util.ts
new file mode 100644
index 0000000000000..9802c8f128f73
--- /dev/null
+++ b/browser/src/app/Util.ts
@@ -0,0 +1,298 @@
+/* -*- js-indent-level: 8 -*- */
+/*
+ * Copyright the Collabora Online contributors.
+ *
+ * SPDX-License-Identifier: MPL-2.0
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+declare var brandProductFAQURL: string | undefined;
+
+interface IDAble {
+ _leaflet_id: number;
+ [name: string]: any;
+}
+
+type CallbackFunctionVariadic = (...args: any[]) => void;
+
+class Util {
+ private static lastId = 0;
+ private static nextId(): number {
+ return ++Util.lastId;
+ }
+
+ /// Returns the id of the object. Initializes it if necessary.
+ public static stamp(obj: IDAble): number {
+ if (obj._leaflet_id > 0) {
+ return obj._leaflet_id;
+ }
+ obj._leaflet_id = Util.nextId();
+ return obj._leaflet_id;
+ }
+
+ // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
+ public static merge(one: any, two: any): any {
+ return { ...one, ...two };
+ }
+
+ // return a function that won't be called more often than the given interval
+ public static throttle(
+ fn: CallbackFunctionVariadic,
+ time: number,
+ // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
+ context: any,
+ ): CallbackFunctionVariadic {
+ let lock: boolean = false;
+ // eslint-disable-next-line prefer-const
+ let wrapperFn: CallbackFunctionVariadic;
+ let args: any[] | boolean = false;
+
+ const later = function () {
+ // reset lock and call if queued.
+ lock = false;
+ if (args) {
+ wrapperFn.apply(context, args);
+ args = false;
+ }
+ };
+
+ wrapperFn = function (...args_: any[]) {
+ if (lock) {
+ // called too soon, queue to call later
+ args = args_;
+ } else {
+ // call and lock until later
+ fn.apply(context, args_);
+ setTimeout(later, time);
+ lock = true;
+ }
+ };
+
+ return wrapperFn;
+ }
+
+ // wrap the given number to lie within a certain range (used for wrapping longitude)
+ public static wrapNum(
+ x: number,
+ range: Array,
+ includeMax: boolean,
+ ): number {
+ const max = range[1];
+ const min = range[0];
+ const d = max - min;
+ return x === max && includeMax ? x : ((((x - min) % d) + d) % d) + min;
+ }
+
+ // do nothing (used as a noop throughout the code)
+ public static falseFn(): boolean {
+ return false;
+ }
+
+ // round a given number to a given precision
+ public static formatNum(num: number, digits: number): number {
+ var pow = Math.pow(10, digits || 5);
+ return Math.round(num * pow) / pow;
+ }
+
+ // removes prefix from string if string starts with that prefix
+ public static trimStart(str: string, prefix: string): string {
+ if (str.indexOf(prefix) === 0) return str.substring(prefix.length);
+ return str;
+ }
+
+ // removes suffix from string if string ends with that suffix
+ public static trimEnd(str: string, suffix: string): string {
+ var suffixIndex = str.lastIndexOf(suffix);
+ if (suffixIndex !== -1 && str.length - suffix.length === suffixIndex)
+ return str.substring(0, suffixIndex);
+ return str;
+ }
+
+ // removes given prefix and suffix from the string if exists
+ // if suffix is not specifed prefix is trimmed from both end of string
+ // trim whitespace from both sides of a string if prefix and suffix are not given
+ public static trim(str: string, prefix?: string, suffix?: string): string {
+ if (!prefix) return str.trim ? str.trim() : str.replace(/^\s+|\s+$/g, '');
+ let result = Util.trimStart(str, prefix);
+ result = Util.trimEnd(result, suffix);
+ return result;
+ }
+
+ // split a string into words
+ public static splitWords(str: string): string[] {
+ return Util.trim(str).split(/\s+/);
+ }
+
+ public static round(x: number, e?: number): number {
+ if (!e) {
+ return Math.round(x);
+ }
+ var f = 1.0 / e;
+ return Math.round(x * f) * e;
+ }
+
+ public static templateRe = /\{ *([\w_]+) *\}/g;
+
+ // super-simple templating facility, used for TileLayer URLs
+ // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
+ public static template(str: string, data: any): string {
+ return str.replace(Util.templateRe, function (str, key) {
+ let value: any = data[key];
+
+ if (value === undefined) {
+ throw new Error('No value provided for variable ' + str);
+ } else if (typeof value === 'function') {
+ value = value(data);
+ }
+ return value;
+ });
+ }
+
+ public static isArray =
+ Array.isArray ||
+ function (obj) {
+ return Object.prototype.toString.call(obj) === '[object Array]';
+ };
+
+ // minimal image URI, set to an image when disposing to flush memory
+ public static emptyImageUrl =
+ 'data:image/gif;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs=';
+
+ public static toggleFullScreen(): void {
+ const doc = document as any;
+ if (
+ !doc.fullscreenElement &&
+ !doc.mozFullscreenElement &&
+ !doc.msFullscreenElement &&
+ !doc.webkitFullscreenElement
+ ) {
+ if (doc.documentElement.requestFullscreen) {
+ doc.documentElement.requestFullscreen();
+ } else if (doc.documentElement.msRequestFullscreen) {
+ doc.documentElement.msRequestFullscreen();
+ } else if (doc.documentElement.mozRequestFullScreen) {
+ doc.documentElement.mozRequestFullScreen();
+ } else if (doc.documentElement.webkitRequestFullscreen) {
+ doc.documentElement.webkitRequestFullscreen(
+ (Element as any).ALLOW_KEYBOARD_INPUT,
+ );
+ }
+ } else if (doc.exitFullscreen) {
+ doc.exitFullscreen();
+ } else if (doc.msExitFullscreen) {
+ doc.msExitFullscreen();
+ } else if (doc.mozCancelFullScreen) {
+ doc.mozCancelFullScreen();
+ } else if (doc.webkitExitFullscreen) {
+ doc.webkitExitFullscreen();
+ }
+ }
+
+ // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
+ public static isEmpty(o: any): boolean {
+ return !(o && o.length);
+ }
+
+ public static mm100thToInch(mm: number): number {
+ return mm / 2540;
+ }
+
+ private static _canvas: HTMLCanvasElement | null = null;
+
+ private static getTempCanvas(): HTMLCanvasElement {
+ if (Util._canvas) {
+ return Util._canvas;
+ }
+ Util._canvas = document.createElement('canvas');
+ return Util._canvas;
+ }
+
+ public static getTextWidth(text: string, font: string): number {
+ const canvas = Util.getTempCanvas();
+ const context = canvas.getContext('2d');
+ context.font = font;
+ const metrics = context.measureText(text);
+ return Math.floor(metrics.width);
+ }
+
+ public static getProduct(): string {
+ let brandFAQURL =
+ typeof brandProductFAQURL !== 'undefined'
+ ? brandProductFAQURL
+ : 'https://collaboraonline.github.io/post/faq/';
+ const customWindow = window as any;
+ if (customWindow.feedbackUrl && customWindow.buyProductUrl) {
+ const integratorUrl = encodeURIComponent(customWindow.buyProductUrl);
+ brandFAQURL = customWindow.feedbackUrl;
+ brandFAQURL =
+ brandFAQURL.substring(0, brandFAQURL.lastIndexOf('/')) +
+ '/product.html?integrator=' +
+ integratorUrl;
+ }
+ return brandFAQURL;
+ }
+
+ public static replaceCtrlAltInMac(msg: string): string {
+ if (L.Browser.mac) {
+ var ctrl = /Ctrl/g;
+ var alt = /Alt/g;
+ const CustomString = String as any;
+ if (
+ CustomString.locale.startsWith('de') ||
+ CustomString.locale.startsWith('dsb') ||
+ CustomString.locale.startsWith('hsb')
+ ) {
+ ctrl = /Strg/g;
+ }
+ if (CustomString.locale.startsWith('lt')) {
+ ctrl = /Vald/g;
+ }
+ if (CustomString.locale.startsWith('sl')) {
+ ctrl = /Krmilka/gi;
+ alt = /Izmenjalka/gi;
+ }
+ return msg.replace(ctrl, '⌘').replace(alt, '⌥');
+ }
+ return msg;
+ }
+
+ public static randomString(len: number): string {
+ let result = '';
+ const ValidCharacters =
+ '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
+ for (let i = 0; i < len; i++) {
+ result += ValidCharacters.charAt(
+ Math.floor(Math.random() * ValidCharacters.length),
+ );
+ }
+ return result;
+ }
+
+ public static requestAnimFrame(
+ fn: () => void,
+ // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
+ context: any,
+ immediate?: boolean,
+ ): number {
+ if (immediate) {
+ fn.call(context);
+ return 0;
+ }
+
+ return window.requestAnimationFrame(fn.bind(context));
+ }
+
+ public static cancelAnimFrame(id: number): void {
+ if (id) {
+ window.cancelAnimationFrame(id);
+ }
+ }
+
+ public static MAX_SAFE_INTEGER = Math.pow(2, 3) - 1;
+ public static MIN_SAFE_INTEGER = Util.MAX_SAFE_INTEGER;
+}
+
+app.util = Util;
diff --git a/browser/src/canvas/sections/CommentListSection.ts b/browser/src/canvas/sections/CommentListSection.ts
index 7d792ccaa3edc..87556fc31d00c 100644
--- a/browser/src/canvas/sections/CommentListSection.ts
+++ b/browser/src/canvas/sections/CommentListSection.ts
@@ -569,7 +569,7 @@ export class CommentSection extends app.definitions.canvasSectionObject {
var tdAuthor = L.DomUtil.create(tagTd, 'cool-annotation-author', tr);
var imgAuthor = L.DomUtil.create('img', 'avatar-img', tdImg);
var user = this.map.getViewId(commentData.author);
- L.LOUtil.setUserImage(imgAuthor, this.map, user);
+ app.LOUtil.setUserImage(imgAuthor, this.map, user);
imgAuthor.setAttribute('width', 32);
imgAuthor.setAttribute('height', 32);
var authorAvatarImg = imgAuthor;
@@ -579,7 +579,7 @@ export class CommentSection extends app.definitions.canvasSectionObject {
$(contentAuthor).text(commentData.author);
$(authorAvatarImg).attr('src', commentData.avatar);
if (user >= 0) {
- var color = L.LOUtil.rgbToHex(this.map.getViewColor(user));
+ var color = app.LOUtil.rgbToHex(this.map.getViewColor(user));
$(authorAvatarImg).css('border-color', color);
}
@@ -1361,7 +1361,7 @@ export class CommentSection extends app.definitions.canvasSectionObject {
redline.anchorPix = this.numberArrayToCorePixFromTwips(redline.anchorPos, 0, 2);
redline.trackchange = true;
redline.text = redline.comment;
- var rectangles = L.PolyUtil.rectanglesToPolygons(L.LOUtil.stringToRectangles(redline.textRange), app.map._docLayer);
+ var rectangles = L.PolyUtil.rectanglesToPolygons(app.LOUtil.stringToRectangles(redline.textRange), app.map._docLayer);
if (rectangles.length > 0) {
redline.textSelected = L.polygon(rectangles, {
pointerEvents: 'all',
@@ -1780,7 +1780,7 @@ export class CommentSection extends app.definitions.canvasSectionObject {
comment.parthash = comment.parthash ? comment.parthash: null;
var viewId = this.map.getViewId(comment.author);
- var color = viewId >= 0 ? L.LOUtil.rgbToHex(this.map.getViewColor(viewId)) : '#43ACE8';
+ var color = viewId >= 0 ? app.LOUtil.rgbToHex(this.map.getViewColor(viewId)) : '#43ACE8';
comment.color = color;
}
@@ -1811,7 +1811,7 @@ export class CommentSection extends app.definitions.canvasSectionObject {
}
var viewId = this.map.getViewId(comment.author);
- var color = viewId >= 0 ? L.LOUtil.rgbToHex(this.map.getViewColor(viewId)) : '#43ACE8';
+ var color = viewId >= 0 ? app.LOUtil.rgbToHex(this.map.getViewColor(viewId)) : '#43ACE8';
comment.color = color;
}
diff --git a/browser/src/canvas/sections/CommentSection.ts b/browser/src/canvas/sections/CommentSection.ts
index f4763aac5fc0e..3837cdd0c4799 100644
--- a/browser/src/canvas/sections/CommentSection.ts
+++ b/browser/src/canvas/sections/CommentSection.ts
@@ -279,7 +279,7 @@ export class Comment extends CanvasSectionObject {
var tdAuthor = L.DomUtil.create('td', 'cool-annotation-author', tr);
var imgAuthor = L.DomUtil.create('img', 'avatar-img', tdImg);
var viewId = this.map.getViewId(this.sectionProperties.data.author);
- L.LOUtil.setUserImage(imgAuthor, this.map, viewId);
+ app.LOUtil.setUserImage(imgAuthor, this.map, viewId);
imgAuthor.setAttribute('width', this.sectionProperties.imgSize[0]);
imgAuthor.setAttribute('height', this.sectionProperties.imgSize[1]);
@@ -471,7 +471,7 @@ export class Comment extends CanvasSectionObject {
}
var user = this.map.getViewId(this.sectionProperties.data.author);
if (user >= 0) {
- var color = L.LOUtil.rgbToHex(this.map.getViewColor(user));
+ var color = app.LOUtil.rgbToHex(this.map.getViewColor(user));
this.sectionProperties.authorAvatartdImg.style.borderColor = color;
}
diff --git a/browser/src/canvas/sections/ContentControlSection.ts b/browser/src/canvas/sections/ContentControlSection.ts
index 05e234ca17d82..984751ff85a43 100644
--- a/browser/src/canvas/sections/ContentControlSection.ts
+++ b/browser/src/canvas/sections/ContentControlSection.ts
@@ -181,7 +181,7 @@ export class ContentControlSection extends CanvasSectionObject {
var fontStyle = getComputedStyle(document.body).getPropertyValue('--docs-font').split(',')[0].replace(/'/g, '');
var fontSize = getComputedStyle(document.body).getPropertyValue('--default-font-size');
var font = fontSize + ' ' + fontStyle;
- var textWidth: number = L.Util.getTextWidth(text, font) + padding;
+ var textWidth: number = app.util.getTextWidth(text, font) + padding;
// draw rectangle with backgroundcolor
this.context.beginPath();
diff --git a/browser/src/canvas/sections/OtherViewCellCursorSection.ts b/browser/src/canvas/sections/OtherViewCellCursorSection.ts
index 163704705bb12..b70767fae6144 100644
--- a/browser/src/canvas/sections/OtherViewCellCursorSection.ts
+++ b/browser/src/canvas/sections/OtherViewCellCursorSection.ts
@@ -27,7 +27,7 @@ class OtherViewCellCursorSection extends CanvasSectionObject {
this.size = [rectangle.pWidth, rectangle.pHeight];
this.position = [rectangle.pX1, rectangle.pY1];
- this.sectionProperties.color = L.LOUtil.rgbToHex(L.LOUtil.getViewIdColor(viewId));
+ this.sectionProperties.color = app.LOUtil.rgbToHex(app.LOUtil.getViewIdColor(viewId));
this.name = OtherViewCellCursorSection.sectionNamePrefix + viewId;
this.sectionProperties.viewId = viewId;
diff --git a/browser/src/canvas/sections/OtherViewCursorSection.ts b/browser/src/canvas/sections/OtherViewCursorSection.ts
index 6d85dadcf16f6..3337478b47a24 100644
--- a/browser/src/canvas/sections/OtherViewCursorSection.ts
+++ b/browser/src/canvas/sections/OtherViewCursorSection.ts
@@ -58,7 +58,7 @@ class OtherViewCursorSection extends HTMLObjectSection {
public static addOrUpdateOtherViewCursor(viewId: number, username: string, rectangleData: Array, part: number, mode: number) {
let rectangle = new cool.SimpleRectangle(0, 0, 0, 0);
- const color = L.LOUtil.rgbToHex(L.LOUtil.getViewIdColor(viewId));
+ const color = app.LOUtil.rgbToHex(app.LOUtil.getViewIdColor(viewId));
if (rectangleData) {
rectangle = new app.definitions.simpleRectangle(rectangleData[0], rectangleData[1], rectangleData[2], rectangleData[3]);
diff --git a/browser/src/canvas/sections/OtherViewGraphicSelectionSection.ts b/browser/src/canvas/sections/OtherViewGraphicSelectionSection.ts
index 061ba700da856..f3e65e7425578 100644
--- a/browser/src/canvas/sections/OtherViewGraphicSelectionSection.ts
+++ b/browser/src/canvas/sections/OtherViewGraphicSelectionSection.ts
@@ -27,7 +27,7 @@ class OtherViewGraphicSelectionSection extends CanvasSectionObject {
this.size = [rectangle.pWidth, rectangle.pHeight];
this.position = [rectangle.pX1, rectangle.pY1];
- this.sectionProperties.color = L.LOUtil.rgbToHex(L.LOUtil.getViewIdColor(viewId));
+ this.sectionProperties.color = app.LOUtil.rgbToHex(app.LOUtil.getViewIdColor(viewId));
this.name = OtherViewGraphicSelectionSection.sectionNamePrefix + viewId;
this.sectionProperties.viewId = viewId;
diff --git a/browser/src/canvas/sections/URLPopUpSection.ts b/browser/src/canvas/sections/URLPopUpSection.ts
index d1c820b507475..bda0ed03ad476 100644
--- a/browser/src/canvas/sections/URLPopUpSection.ts
+++ b/browser/src/canvas/sections/URLPopUpSection.ts
@@ -58,7 +58,7 @@ class URLPopUpSection extends HTMLObjectSection {
copyBtn.setAttribute('title', _('Copy link location'));
const imgCopyBtn = L.DomUtil.create('img', 'hyperlink-pop-up-copyimg', copyBtn);
- L.LOUtil.setImage(imgCopyBtn, 'lc_copyhyperlinklocation.svg', app.map);
+ app.LOUtil.setImage(imgCopyBtn, 'lc_copyhyperlinklocation.svg', app.map);
imgCopyBtn.setAttribute('width', 18);
imgCopyBtn.setAttribute('height', 18);
imgCopyBtn.style.padding = '4px';
@@ -68,7 +68,7 @@ class URLPopUpSection extends HTMLObjectSection {
editBtn.setAttribute('title', _('Edit link'));
const imgEditBtn = L.DomUtil.create('img', 'hyperlink-pop-up-editimg', editBtn);
- L.LOUtil.setImage(imgEditBtn, 'lc_edithyperlink.svg', app.map);
+ app.LOUtil.setImage(imgEditBtn, 'lc_edithyperlink.svg', app.map);
imgEditBtn.setAttribute('width', 18);
imgEditBtn.setAttribute('height', 18);
imgEditBtn.style.padding = '4px';
@@ -78,7 +78,7 @@ class URLPopUpSection extends HTMLObjectSection {
removeBtn.setAttribute('title', _('Remove link'));
const imgRemoveBtn = L.DomUtil.create('img', 'hyperlink-pop-up-removeimg', removeBtn);
- L.LOUtil.setImage(imgRemoveBtn, 'lc_removehyperlink.svg', app.map);
+ app.LOUtil.setImage(imgRemoveBtn, 'lc_removehyperlink.svg', app.map);
imgRemoveBtn.setAttribute('width', 18);
imgRemoveBtn.setAttribute('height', 18);
imgRemoveBtn.style.padding = '4px';
diff --git a/browser/src/control/Control.AboutDialog.ts b/browser/src/control/Control.AboutDialog.ts
index e72439db296cd..ac0e61fe9db9f 100644
--- a/browser/src/control/Control.AboutDialog.ts
+++ b/browser/src/control/Control.AboutDialog.ts
@@ -178,7 +178,7 @@ class AboutDialog {
_('Copy all version information in English'),
);
var img = L.DomUtil.create('img', null, null);
- L.LOUtil.setImage(img, 'lc_copy.svg', this.map);
+ app.LOUtil.setImage(img, 'lc_copy.svg', this.map);
copyversion.innerHTML =
'
';
copyversion.addEventListener(
@@ -285,9 +285,9 @@ class AboutDialog {
const copybutton = document.querySelector(
'#modal-dialog-about-dialog-box-copybutton > img',
);
- L.LOUtil.setImage(copybutton, 'lc_clipboard-check.svg', this.map);
+ app.LOUtil.setImage(copybutton, 'lc_clipboard-check.svg', this.map);
setTimeout(() => {
- L.LOUtil.setImage(copybutton, 'lc_copy.svg', this.map);
+ app.LOUtil.setImage(copybutton, 'lc_copy.svg', this.map);
}, timeout);
}
diff --git a/browser/src/control/Control.Command.js b/browser/src/control/Control.Command.js
index 49c350dafd5cb..986ca75eed01f 100644
--- a/browser/src/control/Control.Command.js
+++ b/browser/src/control/Control.Command.js
@@ -12,7 +12,7 @@
* Feature blocking handler
*/
-/* global $ _ */
+/* global $ _ app */
L.Map.include({
@@ -56,7 +56,7 @@ L.Map.include({
if (window.mode.isMobile()) {
var overlay = L.DomUtil.create('div', 'locking-overlay', DOMParentElement);
var lock = L.DomUtil.create('img', 'locking-overlay-lock', overlay);
- L.LOUtil.setImage(lock, 'lc_lock.svg', this);
+ app.LOUtil.setImage(lock, 'lc_lock.svg', this);
}
$(DOMParentElement).click(function(event) {
diff --git a/browser/src/control/Control.DownloadProgress.js b/browser/src/control/Control.DownloadProgress.js
index a4553ceb80c4e..bb657bc585bde 100644
--- a/browser/src/control/Control.DownloadProgress.js
+++ b/browser/src/control/Control.DownloadProgress.js
@@ -57,7 +57,7 @@ L.Control.DownloadProgress = L.Control.extend({
var modalId = this._getDownloadProgressDialogId();
var msg = this._getLargeCopyPasteMessage();
- var buttonText = _('Download') + L.Util.replaceCtrlAltInMac(' (Ctrl + C)');
+ var buttonText = _('Download') + app.util.replaceCtrlAltInMac(' (Ctrl + C)');
if (inSnackbar) {
this._map.uiManager.showSnackbar(
@@ -83,7 +83,7 @@ L.Control.DownloadProgress = L.Control.extend({
this._map.uiManager.showProgressBar(msg, buttonText, this._onClose.bind(this));
} else if (this._isLargeCopy) {
// downloading for copy, next: show download complete dialog
- buttonText = _('Copy') + L.Util.replaceCtrlAltInMac(' (Ctrl + C)');
+ buttonText = _('Copy') + app.util.replaceCtrlAltInMac(' (Ctrl + C)');
this._map.uiManager.showProgressBarDialog(modalId, this._getDialogTitle(), msg,
buttonText, this._onConfirmCopyAction.bind(this), 0, this._onClose.bind(this));
@@ -108,7 +108,7 @@ L.Control.DownloadProgress = L.Control.extend({
var modalId = this._getDownloadProgressDialogId();
var snackbarMsg = _('Download completed and ready to be copied to clipboard.');
var dialogMsg = snackbarMsg + ' ' + _('From now on clipboard notifications will discreetly appear at the bottom.');
- var buttonText = _('Copy') + L.Util.replaceCtrlAltInMac(' (Ctrl + C)');
+ var buttonText = _('Copy') + app.util.replaceCtrlAltInMac(' (Ctrl + C)');
if (inSnackbar) {
this._map.uiManager.setSnackbarProgress(100);
diff --git a/browser/src/control/Control.IdleHandler.ts b/browser/src/control/Control.IdleHandler.ts
index d90dc1fe9256a..b0e9aae429f7d 100644
--- a/browser/src/control/Control.IdleHandler.ts
+++ b/browser/src/control/Control.IdleHandler.ts
@@ -187,13 +187,13 @@ class IdleHandler {
if (message === '') {
document.getElementById(dialogId).style.display = 'none';
- L.LOUtil.onRemoveHTMLElement(document.getElementById(this.dimId), restartConnection);
+ app.LOUtil.onRemoveHTMLElement(document.getElementById(this.dimId), restartConnection);
}
else {
var overlayId = dialogId + '-overlay';
var overlay = document.getElementById(overlayId);
overlay.onmouseover = () => { restartConnection(); uiManager.closeModal(dialogId); };
- L.LOUtil.onRemoveHTMLElement(overlay, restartConnection);
+ app.LOUtil.onRemoveHTMLElement(overlay, restartConnection);
}
this._sendInactiveMessage();
diff --git a/browser/src/control/Control.JSDialogBuilder.js b/browser/src/control/Control.JSDialogBuilder.js
index 98cdae8c2a1d7..803fb8b6027da 100644
--- a/browser/src/control/Control.JSDialogBuilder.js
+++ b/browser/src/control/Control.JSDialogBuilder.js
@@ -420,7 +420,7 @@ L.Control.JSDialogBuilder = L.Control.extend({
for (var i = 0; i < handlers.length; ++i) {
var event = handlers[i].event;
var handler = handlers[i].handler;
- if (!L.isEmpty(event) && handler) {
+ if (!app.util.isEmpty(event) && handler) {
if (event === 'click') {
var eventData = {
id: controlElement.id
@@ -608,7 +608,7 @@ L.Control.JSDialogBuilder = L.Control.extend({
}
if (iconURL) {
var icon = L.DomUtil.create('img', 'menu-entry-icon', leftDiv);
- L.LOUtil.setImage(icon, iconURL, builder.map);
+ app.LOUtil.setImage(icon, iconURL, builder.map);
icon.alt = '';
titleClass = 'menu-entry-with-icon';
@@ -814,12 +814,12 @@ L.Control.JSDialogBuilder = L.Control.extend({
$(sectionTitle).css('justify-content', 'space-between');
var commandName = dataid;
- if (commandName && commandName.length && L.LOUtil.existsIconForCommand(commandName, builder.map.getDocType())) {
+ if (commandName && commandName.length && app.LOUtil.existsIconForCommand(commandName, builder.map.getDocType())) {
var iconName = builder._generateMenuIconName(commandName);
var iconSpan = L.DomUtil.create('span', 'menu-entry-icon ' + iconName, sectionTitle);
iconName = builder._createIconURL(iconName, true);
icon = L.DomUtil.create('img', '', iconSpan);
- L.LOUtil.setImage(icon, iconName, builder.map);
+ app.LOUtil.setImage(icon, iconName, builder.map);
icon.alt = '';
var titleSpan2 = L.DomUtil.create('span', 'menu-entry-with-icon flex-fullwidth', sectionTitle);
titleSpan2.innerHTML = title;
@@ -1541,7 +1541,7 @@ L.Control.JSDialogBuilder = L.Control.extend({
} else if (data.symbol) {
L.DomUtil.addClass(pushbutton, 'has-img d-flex align-content-center justify-content-center align-items-center');
image = L.DomUtil.create('img', '', pushbutton);
- L.LOUtil.setImage(image, 'symbol_' + data.symbol + '.svg', builder.map);
+ app.LOUtil.setImage(image, 'symbol_' + data.symbol + '.svg', builder.map);
} else {
pushbutton.innerText = pushbuttonText;
builder._stressAccessKey(pushbutton, pushbutton.accessKey);
@@ -1712,13 +1712,13 @@ L.Control.JSDialogBuilder = L.Control.extend({
if (image) {
image = image.substr(0, image.lastIndexOf('.'));
image = image.substr(image.lastIndexOf('/') + 1);
- image = 'url("' + L.LOUtil.getImageURL(image + '.svg') + '")';
+ image = 'url("' + app.LOUtil.getImageURL(image + '.svg') + '")';
}
if (image64) {
image = 'url("' + image64 + '")';
}
- L.LOUtil.checkIfImageExists(image);
+ app.LOUtil.checkIfImageExists(image);
elem = L.DomUtil.create('div', 'layout ' +
(data.entries[index].selected ? ' cool-context-down' : ''), parentContainer);
$(elem).data('id', data.entries[index].id);
@@ -1946,7 +1946,7 @@ L.Control.JSDialogBuilder = L.Control.extend({
L.DomUtil.addClass(parentContainer, 'content-has-no-comments');
var emptyCommentWizard = L.DomUtil.create('figure', 'empty-comment-wizard-container', parentContainer);
var imgNode = L.DomUtil.create('img', 'empty-comment-wizard-img', emptyCommentWizard);
- L.LOUtil.setImage(imgNode, 'lc_showannotations.svg', builder.map);
+ app.LOUtil.setImage(imgNode, 'lc_showannotations.svg', builder.map);
imgNode.alt = data.text;
var textNode = L.DomUtil.create('figcaption', 'empty-comment-wizard', emptyCommentWizard);
@@ -2287,7 +2287,7 @@ L.Control.JSDialogBuilder = L.Control.extend({
else if (hasImage !== false){
if (data.icon) {
buttonImage = L.DomUtil.create('img', '', button);
- this._isStringCloseToURL(data.icon) ? buttonImage.src = data.icon : L.LOUtil.setImage(buttonImage, data.icon, builder.map);
+ this._isStringCloseToURL(data.icon) ? buttonImage.src = data.icon : app.LOUtil.setImage(buttonImage, data.icon, builder.map);
}
else if (data.image) {
buttonImage = L.DomUtil.create('img', '', button);
@@ -2295,7 +2295,7 @@ L.Control.JSDialogBuilder = L.Control.extend({
}
else {
buttonImage = L.DomUtil.create('img', '', button);
- L.LOUtil.setImage(buttonImage, builder._createIconURL(data.command), builder.map);
+ app.LOUtil.setImage(buttonImage, builder._createIconURL(data.command), builder.map);
}
} else {
buttonImage = false;
@@ -2672,12 +2672,12 @@ L.Control.JSDialogBuilder = L.Control.extend({
var icon = null;
var commandName = data.command && data.command.startsWith('.uno:') ? data.command.substring('.uno:'.length) : data.id;
- if (commandName && commandName.length && L.LOUtil.existsIconForCommand(commandName, builder.map.getDocType())) {
+ if (commandName && commandName.length && app.LOUtil.existsIconForCommand(commandName, builder.map.getDocType())) {
var iconName = builder._generateMenuIconName(commandName);
var iconSpan = L.DomUtil.create('span', 'menu-entry-icon ' + iconName, menuEntry);
iconName = builder._createIconURL(iconName, true);
icon = L.DomUtil.create('img', '', iconSpan);
- L.LOUtil.setImage(icon, iconName, builder.map);
+ app.LOUtil.setImage(icon, iconName, builder.map);
icon.alt = '';
}
if (data.checked && data.checked === true) {
diff --git a/browser/src/control/Control.Layers.js b/browser/src/control/Control.Layers.js
index 5b04da8829d62..270f4735d76b7 100644
--- a/browser/src/control/Control.Layers.js
+++ b/browser/src/control/Control.Layers.js
@@ -1,4 +1,5 @@
/* -*- js-indent-level: 8 -*- */
+/* global app */
/*
* L.Control.Layers is a control to allow users to switch between different layers on the map.
*/
@@ -37,7 +38,7 @@ L.Control.Layers = L.Control.extend({
removeLayer: function (layer) {
layer.off('add remove', this._onLayerChange, this);
- delete this._layers[L.stamp(layer)];
+ delete this._layers[app.util.stamp(layer)];
return this._update();
},
@@ -93,7 +94,7 @@ L.Control.Layers = L.Control.extend({
_addLayer: function (layer, name, overlay) {
layer.on('add remove', this._onLayerChange, this);
- var id = L.stamp(layer);
+ var id = app.util.stamp(layer);
this._layers[id] = {
layer: layer,
@@ -139,7 +140,7 @@ L.Control.Layers = L.Control.extend({
this._update();
}
- var overlay = this._layers[L.stamp(e.target)].overlay;
+ var overlay = this._layers[app.util.stamp(e.target)].overlay;
var type = overlay ?
(e.type === 'add' ? 'overlayadd' : 'overlayremove') :
@@ -176,7 +177,7 @@ L.Control.Layers = L.Control.extend({
input = this._createRadioElement('leaflet-base-layers', checked);
}
- input.layerId = L.stamp(obj.layer);
+ input.layerId = app.util.stamp(obj.layer);
L.DomEvent.on(input, 'click', this._onInputClick, this);
diff --git a/browser/src/control/Control.Menubar.js b/browser/src/control/Control.Menubar.js
index a068888458aa5..26ba20fe2e08d 100644
--- a/browser/src/control/Control.Menubar.js
+++ b/browser/src/control/Control.Menubar.js
@@ -1,4 +1,5 @@
/* -*- js-indent-level: 8 -*- */
+/* global app */
/*
* Copyright the Collabora Online contributors.
*
@@ -53,7 +54,7 @@ L.Control.MenubarShortcuts = {
shortcut = shortcut.replace('Ctrl', 'Krmilka').replace('Alt', 'izmenjalka').replace('Shift', 'dvigalka');
}
- var newText = _(text).replace('~', '') + ' (' + L.Util.replaceCtrlAltInMac(shortcut) + ')';
+ var newText = _(text).replace('~', '') + ' (' + app.util.replaceCtrlAltInMac(shortcut) + ')';
return newText;
}
@@ -2082,7 +2083,7 @@ L.Control.Menubar = L.Control.extend({
} else if (id === 'zoomreset') {
app.dispatcher.dispatch('zoomreset');
} else if (id === 'fullscreen') {
- L.toggleFullScreen();
+ app.util.toggleFullScreen();
} else if (id === 'showruler') {
app.dispatcher.dispatch('showruler');
} else if (id === 'togglea11ystate') {
@@ -2529,7 +2530,7 @@ L.Control.Menubar = L.Control.extend({
},
_initializeMenu: function(menu) {
- this._isFileODF = L.LOUtil.isFileODF(this._map);
+ this._isFileODF = app.LOUtil.isFileODF(this._map);
var menuHtml = this._createMenu(menu);
for (var i in menuHtml) {
this._menubarCont.appendChild(menuHtml[i]);
diff --git a/browser/src/control/Control.MobileWizardBuilder.js b/browser/src/control/Control.MobileWizardBuilder.js
index 5d9f1ce1ec002..2b98b7943fc34 100644
--- a/browser/src/control/Control.MobileWizardBuilder.js
+++ b/browser/src/control/Control.MobileWizardBuilder.js
@@ -14,7 +14,7 @@
* variants for mobile/touch devices from the JSON description provided by the server.
*/
-/* global $ _UNO _ JSDialog */
+/* global $ _UNO _ JSDialog app */
L.Control.MobileWizardBuilder = L.Control.JSDialogBuilder.extend({
_customizeOptions: function() {
@@ -77,10 +77,10 @@ L.Control.MobileWizardBuilder = L.Control.JSDialogBuilder.extend({
div.id = data.id;
controls['container'] = div;
var commandName = data.id && data.id.startsWith('.uno:') ? data.id.substring('.uno:'.length) : data.id;
- if (commandName && commandName.length && L.LOUtil.existsIconForCommand(commandName, builder.map.getDocType())) {
+ if (commandName && commandName.length && app.LOUtil.existsIconForCommand(commandName, builder.map.getDocType())) {
var image = L.DomUtil.create('img', 'spinfieldimage', div);
var icon = (data.id === 'Transparency') ? builder._createIconURL('settransparency') : builder._createIconURL(data.id);
- L.LOUtil.setImage(image, icon, builder.map);
+ app.LOUtil.setImage(image, icon, builder.map);
icon.alt = '';
}
diff --git a/browser/src/control/Control.MobileWizardWindow.js b/browser/src/control/Control.MobileWizardWindow.js
index 4801422a36128..0204548326c35 100644
--- a/browser/src/control/Control.MobileWizardWindow.js
+++ b/browser/src/control/Control.MobileWizardWindow.js
@@ -618,13 +618,13 @@ L.Control.MobileWizardWindow = L.Control.extend({
},
_isSlidePropertyPanel: function(data) {
- var backgroundPanel = L.LOUtil.findItemWithAttributeRecursive(data, 'id', 'SlideBackgroundPanel');
- var layoutPanel = L.LOUtil.findItemWithAttributeRecursive(data, 'id', 'SdLayoutsPanel');
+ var backgroundPanel = app.LOUtil.findItemWithAttributeRecursive(data, 'id', 'SlideBackgroundPanel');
+ var layoutPanel = app.LOUtil.findItemWithAttributeRecursive(data, 'id', 'SdLayoutsPanel');
return backgroundPanel && layoutPanel;
},
_insertCalcBorders: function(deck) {
- var replaceMe = L.LOUtil.findItemWithAttributeRecursive(deck, 'id', 'cellbordertype');
+ var replaceMe = app.LOUtil.findItemWithAttributeRecursive(deck, 'id', 'cellbordertype');
if (replaceMe) {
replaceMe.id = 'borderstyle';
replaceMe.type = 'borderstyle';
@@ -638,12 +638,12 @@ L.Control.MobileWizardWindow = L.Control.extend({
if (data.children && data.children.length && data.children[0].type !== 'deck')
data.children.splice(0, 1);
- var deck = L.LOUtil.findItemWithAttributeRecursive(data, 'type', 'deck');
+ var deck = app.LOUtil.findItemWithAttributeRecursive(data, 'type', 'deck');
if (deck)
{
// merge styles into text-panel for elegance
- var stylesIdx = L.LOUtil.findIndexInParentByAttribute(deck, 'id', 'StylesPropertyPanel');
- var textIdx = L.LOUtil.findIndexInParentByAttribute(deck, 'id', 'TextPropertyPanel');
+ var stylesIdx = app.LOUtil.findIndexInParentByAttribute(deck, 'id', 'StylesPropertyPanel');
+ var textIdx = app.LOUtil.findIndexInParentByAttribute(deck, 'id', 'TextPropertyPanel');
if (stylesIdx >= 0 && this.map.getDocType() === 'spreadsheet')
{ // remove rather useless calc styles panel
diff --git a/browser/src/control/Control.NotebookbarCalc.js b/browser/src/control/Control.NotebookbarCalc.js
index b22e1d83e2630..f736c406bae89 100644
--- a/browser/src/control/Control.NotebookbarCalc.js
+++ b/browser/src/control/Control.NotebookbarCalc.js
@@ -13,7 +13,7 @@
* L.Control.NotebookbarCalc - definition of notebookbar content in Calc
*/
-/* global _ _UNO */
+/* global _ _UNO app */
L.Control.NotebookbarCalc = L.Control.NotebookbarWriter.extend({
getTabs: function() {
@@ -1527,7 +1527,7 @@ L.Control.NotebookbarCalc = L.Control.NotebookbarWriter.extend({
'text': _UNO('.uno:FontworkGalleryFloater'),
'command': '.uno:FontworkGalleryFloater',
// Fontwork export/import not supported in other formats.
- 'visible': (L.LOUtil.isFileODF(this._map)) ? 'true' : 'false',
+ 'visible': (app.LOUtil.isFileODF(this._map)) ? 'true' : 'false',
'accessibility': { focusBack: true, combination: 'IF', de: null }
}
]
@@ -2426,7 +2426,7 @@ L.Control.NotebookbarCalc = L.Control.NotebookbarWriter.extend({
'text': _UNO('.uno:FontworkGalleryFloater'),
'command': '.uno:FontworkGalleryFloater',
// Fontwork export/import not supported in other formats.
- 'visible': (L.LOUtil.isFileODF(this._map)) ? 'true' : 'false',
+ 'visible': (app.LOUtil.isFileODF(this._map)) ? 'true' : 'false',
'accessibility': { focusBack: true, combination: 'FW', de: null }
}
]
diff --git a/browser/src/control/Control.NotebookbarDraw.js b/browser/src/control/Control.NotebookbarDraw.js
index 4b9deabe63f40..e4b87a7d85f4e 100644
--- a/browser/src/control/Control.NotebookbarDraw.js
+++ b/browser/src/control/Control.NotebookbarDraw.js
@@ -13,7 +13,7 @@
* L.Control.NotebookbarDraw - definition of notebookbar content in Draw
*/
-/* global _ _UNO */
+/* global _ _UNO app */
L.Control.NotebookbarDraw = L.Control.NotebookbarImpress.extend({
getShortcutsBarData: function() {
@@ -648,7 +648,7 @@ L.Control.NotebookbarDraw = L.Control.NotebookbarImpress.extend({
'text': _UNO('.uno:FontworkGalleryFloater'),
'command': '.uno:FontworkGalleryFloater',
// Fontwork export/import not supported in other formats.
- 'visible': L.LOUtil.isFileODF(this._map) ? 'true' : 'false',
+ 'visible': app.LOUtil.isFileODF(this._map) ? 'true' : 'false',
'accessibility': { focusBack: true, combination: 'FW', de: null }
},
{
@@ -1401,7 +1401,7 @@ L.Control.NotebookbarDraw = L.Control.NotebookbarImpress.extend({
'text': _UNO('.uno:FontworkGalleryFloater'),
'command': '.uno:FontworkGalleryFloater',
// Fontwork export/import not supported in other formats.
- 'visible': L.LOUtil.isFileODF(this._map) ? 'true' : 'false',
+ 'visible': app.LOUtil.isFileODF(this._map) ? 'true' : 'false',
'accessibility': { focusBack: true, combination: 'FG', de: null }
}
]
diff --git a/browser/src/control/Control.NotebookbarImpress.js b/browser/src/control/Control.NotebookbarImpress.js
index 3f25bb798c80d..6e9099dc03337 100644
--- a/browser/src/control/Control.NotebookbarImpress.js
+++ b/browser/src/control/Control.NotebookbarImpress.js
@@ -13,7 +13,7 @@
* L.Control.NotebookbarImpress - definition of notebookbar content in Impress
*/
-/* global _ _UNO */
+/* global _ _UNO app */
L.Control.NotebookbarImpress = L.Control.NotebookbarWriter.extend({
@@ -699,7 +699,7 @@ L.Control.NotebookbarImpress = L.Control.NotebookbarWriter.extend({
'text': _UNO('.uno:FontworkGalleryFloater'),
'command': '.uno:FontworkGalleryFloater',
// Fontwork export/import not supported in other formats.
- 'visible': (L.LOUtil.isFileODF(this._map)) ? 'true' : 'false',
+ 'visible': (app.LOUtil.isFileODF(this._map)) ? 'true' : 'false',
'accessibility': { focusBack: true, combination: 'FL', de: null }
},
{
@@ -1392,7 +1392,7 @@ L.Control.NotebookbarImpress = L.Control.NotebookbarWriter.extend({
'text': _UNO('.uno:FontworkGalleryFloater'),
'command': '.uno:FontworkGalleryFloater',
// Fontwork export/import not supported in other formats.
- 'visible': L.LOUtil.isFileODF(this._map) ? 'true' : 'false',
+ 'visible': app.LOUtil.isFileODF(this._map) ? 'true' : 'false',
'accessibility': { focusBack: true, combination: 'FW', de: null }
}
]
@@ -2455,7 +2455,7 @@ L.Control.NotebookbarImpress = L.Control.NotebookbarWriter.extend({
'text': _UNO('.uno:FontworkGalleryFloater'),
'command': '.uno:FontworkGalleryFloater',
// Fontwork export/import not supported in other formats.
- 'visible': (L.LOUtil.isFileODF(this._map)) ? 'true' : 'false',
+ 'visible': (app.LOUtil.isFileODF(this._map)) ? 'true' : 'false',
'accessibility': { focusBack: true, combination: 'FW', de: null }
}
]
diff --git a/browser/src/control/Control.NotebookbarWriter.js b/browser/src/control/Control.NotebookbarWriter.js
index ea43e86e441e7..a7caa2706d7fe 100644
--- a/browser/src/control/Control.NotebookbarWriter.js
+++ b/browser/src/control/Control.NotebookbarWriter.js
@@ -13,7 +13,7 @@
* L.Control.NotebookbarWriter - definition of notebookbar content in Writer
*/
-/* global _ _UNO */
+/* global _ _UNO app */
var fileTabName = 'File';
var homeTabName = 'Home';
@@ -1078,7 +1078,7 @@ L.Control.NotebookbarWriter = L.Control.Notebookbar.extend({
},
getInsertTab: function() {
- var isODF = L.LOUtil.isFileODF(this._map);
+ var isODF = app.LOUtil.isFileODF(this._map);
var content = [
{
'id': 'insert-insert-page-break',
@@ -2675,7 +2675,7 @@ L.Control.NotebookbarWriter = L.Control.Notebookbar.extend({
},
getDrawTab: function() {
- var isODF = L.LOUtil.isFileODF(this._map);
+ var isODF = app.LOUtil.isFileODF(this._map);
var content = [
{
'type': 'bigtoolitem',
diff --git a/browser/src/control/Control.Tooltip.js b/browser/src/control/Control.Tooltip.js
index bc756510d9bab..f6558dc2b2e58 100644
--- a/browser/src/control/Control.Tooltip.js
+++ b/browser/src/control/Control.Tooltip.js
@@ -13,7 +13,7 @@
* Class Tooltip - tooltip manager
*/
-/* global */
+/* global app */
class Tooltip {
constructor(options) {
@@ -135,7 +135,7 @@ class Tooltip {
do {
rectTooltip = this.position(rectElem, rectCont, index++);
- } while (index < 8 && !L.LOUtil.containsDOMRect(rectView, rectTooltip));
+ } while (index < 8 && !app.LOUtil.containsDOMRect(rectView, rectTooltip));
// containsDOMRect() checks if the tooltip box(rectTooltip) is inside the boundaries of the window(rectView)
this._container.style.left = rectTooltip.left + 'px';
diff --git a/browser/src/control/Control.UserList.ts b/browser/src/control/Control.UserList.ts
index f5daf461de1d7..53b89dc421171 100644
--- a/browser/src/control/Control.UserList.ts
+++ b/browser/src/control/Control.UserList.ts
@@ -11,6 +11,7 @@
/*
* L.Control.UserList
*/
+/* global app */
interface UserExtraInfo {
avatar: string;
@@ -163,7 +164,7 @@ class UserList extends L.Control {
img = L.DomUtil.create('img', 'avatar-img') as HTMLImageElement;
}
- L.LOUtil.setUserImage(img, this.map, viewId);
+ app.LOUtil.setUserImage(img, this.map, viewId);
img.alt = this.options.userAvatarAlt.replace('{user}', username);
@@ -387,7 +388,7 @@ class UserList extends L.Control {
you = true;
} else {
username = e.username;
- color = L.LOUtil.rgbToHex(this.map.getViewColor(e.viewId));
+ color = app.LOUtil.rgbToHex(this.map.getViewColor(e.viewId));
you = false;
}
diff --git a/browser/src/control/Control.Zotero.js b/browser/src/control/Control.Zotero.js
index 41f1e4005970e..805e7c1aacbf7 100644
--- a/browser/src/control/Control.Zotero.js
+++ b/browser/src/control/Control.Zotero.js
@@ -84,7 +84,7 @@ L.Control.Zotero = L.Control.extend({
}
var that = this;
this.citationCluster[values.citationID] = [];
- var citationString = L.Util.trim(values.properties.plainCitation, this.settings.layout.prefix, this.settings.layout.suffix);
+ var citationString = app.util.trim(values.properties.plainCitation, this.settings.layout.prefix, this.settings.layout.suffix);
var citations = citationString.split(this.settings.layout.delimiter);
var itemUriList = [];
values.citationItems.forEach(function(item, i) {
@@ -93,7 +93,7 @@ L.Control.Zotero = L.Control.extend({
var itemUri = item.uris[0];
var citationId = that.extractItemKeyFromLink(itemUri);
that.citationCluster[values.citationID].push(citationId);
- that.citations[citationId] = L.Util.trim(citations[i], that.settings.group.prefix, that.settings.group.suffix);
+ that.citations[citationId] = app.util.trim(citations[i], that.settings.group.prefix, that.settings.group.suffix);
that.setCitationNumber(that.citations[citationId]);
itemUriList.push(itemUri);
});
@@ -520,7 +520,7 @@ L.Control.Zotero = L.Control.extend({
this.settings.citationNumber = 1;
this.citations[citationId] = this.settings.citationNumber++;
} else {
- this.citations[citationId] = L.Util.trim(text, this.settings.layout.prefix, this.settings.layout.suffix);
+ this.citations[citationId] = app.util.trim(text, this.settings.layout.prefix, this.settings.layout.suffix);
}
return this.settings.group.prefix + this.citations[citationId] + this.settings.group.suffix;
@@ -546,7 +546,7 @@ L.Control.Zotero = L.Control.extend({
});
});
- citationString = this.settings.layout.prefix + L.Util.trimEnd(citationString, this.settings.layout.delimiter) + this.settings.layout.suffix;
+ citationString = this.settings.layout.prefix + app.util.trimEnd(citationString, this.settings.layout.delimiter) + this.settings.layout.suffix;
// last-child works here only because its a single chain of nodes
var innerText = citationNode.querySelector('*:last-child');
if (!innerText)
@@ -574,7 +574,7 @@ L.Control.Zotero = L.Control.extend({
getCitationJSONString: function(items) {
var resultJSON = {};
- resultJSON['citationID'] = L.Util.randomString(10);
+ resultJSON['citationID'] = app.util.randomString(10);
var citationNode = this.handleCitationText(items);
@@ -916,7 +916,7 @@ L.Control.Zotero = L.Control.extend({
dataNode.setAttribute('data-version', '3');
var sessionNode = xmlDoc.createElement('session');
- sessionNode.setAttribute('id', L.Util.randomString(8));
+ sessionNode.setAttribute('id', app.util.randomString(8));
dataNode.appendChild(sessionNode);
@@ -1610,10 +1610,10 @@ L.Control.Zotero = L.Control.extend({
field['FieldResult'] = {type: 'string', value: citationString};
} else if (this.getFieldType() === 'ReferenceMark') {
field['TypeName'] = {type: 'string', value: 'SetRef'};
- field['Name'] = {type: 'string', value: 'ZOTERO_ITEM CSL_CITATION ' + cslJSON + ' RND' + L.Util.randomString(10)};
+ field['Name'] = {type: 'string', value: 'ZOTERO_ITEM CSL_CITATION ' + cslJSON + ' RND' + app.util.randomString(10)};
field['Content'] = {type: 'string', value: citationString};
} else if (this.getFieldType() == 'Bookmark') {
- field['Bookmark'] = {type: 'string', value: 'ZOTERO_BREF_' + L.Util.randomString(12)};
+ field['Bookmark'] = {type: 'string', value: 'ZOTERO_BREF_' + app.util.randomString(12)};
field['BookmarkText'] = {type: 'string', value: citationString};
}
@@ -1689,7 +1689,7 @@ L.Control.Zotero = L.Control.extend({
'value': {
'Bookmark': {
'type': 'string',
- 'value': 'ZOTERO_BREF_' + L.Util.randomString(12)
+ 'value': 'ZOTERO_BREF_' + app.util.randomString(12)
},
'BookmarkText': {
'type': 'string',
@@ -1710,10 +1710,10 @@ L.Control.Zotero = L.Control.extend({
field['FieldCommand'] = {type: 'string', value: 'ADDIN ZOTERO_BIBL ' + JSON.stringify(this.settings.bib) + ' CSL_BIBLIOGRAPHY'};
field['FieldResult'] = {type: 'string', value: html};
} else if (this.getFieldType() == 'Bookmark') {
- field['Bookmark'] = {type: 'string', value: 'ZOTERO_BREF_' + L.Util.randomString(12)};
+ field['Bookmark'] = {type: 'string', value: 'ZOTERO_BREF_' + app.util.randomString(12)};
field['BookmarkText'] = {type: 'string', value: html};
} else {
- field['RegionName'] = {type: 'string', value: 'ZOTERO_BIBL ' + JSON.stringify(this.settings.bib) + ' CSL_BIBLIOGRAPHY ' + ' RND' + L.Util.randomString(10)};
+ field['RegionName'] = {type: 'string', value: 'ZOTERO_BIBL ' + JSON.stringify(this.settings.bib) + ' CSL_BIBLIOGRAPHY ' + ' RND' + app.util.randomString(10)};
field['Content'] = {type: 'string', value: html};
}
diff --git a/browser/src/control/Toolbar.js b/browser/src/control/Toolbar.js
index b28521c2281fc..cfe8a630e2e2f 100644
--- a/browser/src/control/Toolbar.js
+++ b/browser/src/control/Toolbar.js
@@ -566,10 +566,10 @@ L.Map.include({
for (i = 0, max = productNameContent.length; i < max; i++) {
productNameContent[i].innerHTML = productNameContent[i].innerHTML.replace('{productname}', productName);
}
- document.getElementById('online-help-content').innerHTML = L.Util.replaceCtrlAltInMac(document.getElementById('online-help-content').innerHTML);
+ document.getElementById('online-help-content').innerHTML = app.util.replaceCtrlAltInMac(document.getElementById('online-help-content').innerHTML);
}
if (id === 'keyboard-shortcuts-content') {
- document.getElementById('keyboard-shortcuts-content').innerHTML = L.Util.replaceCtrlAltInMac(document.getElementById('keyboard-shortcuts-content').innerHTML);
+ document.getElementById('keyboard-shortcuts-content').innerHTML = app.util.replaceCtrlAltInMac(document.getElementById('keyboard-shortcuts-content').innerHTML);
}
var searchInput = document.getElementById('online-help-search-input');
searchInput.setAttribute('placeholder',_('Search'));
diff --git a/browser/src/control/jsdialog/Widget.Combobox.js b/browser/src/control/jsdialog/Widget.Combobox.js
index 14fbe9125ff06..441b0a698af57 100644
--- a/browser/src/control/jsdialog/Widget.Combobox.js
+++ b/browser/src/control/jsdialog/Widget.Combobox.js
@@ -24,7 +24,7 @@
* customEntryRenderer - specifies if entries have custom content which is rendered by the core
*/
-/* global JSDialog $ */
+/* global JSDialog app $ */
JSDialog.comboboxEntry = function (parentContainer, data, builder) {
var entry = L.DomUtil.create('div', 'ui-combobox-entry ' + builder.options.cssClass, parentContainer);
@@ -40,7 +40,7 @@ JSDialog.comboboxEntry = function (parentContainer, data, builder) {
if (data.icon) {
var icon = L.DomUtil.create('img', 'ui-combobox-icon', entry);
- builder._isStringCloseToURL(data.icon) ? icon.src = data.icon : L.LOUtil.setImage(icon, builder._createIconURL(data.icon), builder.map);
+ builder._isStringCloseToURL(data.icon) ? icon.src = data.icon : app.LOUtil.setImage(icon, builder._createIconURL(data.icon), builder.map);
}
if (data.hint) {
diff --git a/browser/src/control/jsdialog/Widget.MobileBorderSelector.js b/browser/src/control/jsdialog/Widget.MobileBorderSelector.js
index f4c1f42059985..f555244a94ed2 100644
--- a/browser/src/control/jsdialog/Widget.MobileBorderSelector.js
+++ b/browser/src/control/jsdialog/Widget.MobileBorderSelector.js
@@ -19,7 +19,7 @@
* }
*/
-/* global _ JSDialog $ */
+/* global _ JSDialog $ app */
function _getCurrentBorderNumber(builder) {
var outer = builder.map['stateChangeHandler'].getItemValue('.uno:BorderOuter');
@@ -69,7 +69,7 @@ function _borderControlItem(parentContainer, data, builder, i, selected) {
var buttonId = 'border-' + i;
button = L.DomUtil.create('img', 'ui-content borderbutton', div);
- L.LOUtil.setImage(button, 'fr0' + i + '.svg', builder.map);
+ app.LOUtil.setImage(button, 'fr0' + i + '.svg', builder.map);
button.id = buttonId;
if (selected)
$(button).addClass('selected');
@@ -77,7 +77,7 @@ function _borderControlItem(parentContainer, data, builder, i, selected) {
$(div).click(function () {
var color = 0;
// Find our associated color picker
- var item = L.LOUtil.findItemWithAttributeRecursive(data.parent, 'command', '.uno:FrameLineColor');
+ var item = app.LOUtil.findItemWithAttributeRecursive(data.parent, 'command', '.uno:FrameLineColor');
if (item)
color = JSDialog.getCurrentColor(item, builder);
window.setBorderStyle(i, color);
diff --git a/browser/src/control/jsdialog/Widget.TreeView.ts b/browser/src/control/jsdialog/Widget.TreeView.ts
index befd741724d5d..2a93fa4611ead 100644
--- a/browser/src/control/jsdialog/Widget.TreeView.ts
+++ b/browser/src/control/jsdialog/Widget.TreeView.ts
@@ -59,6 +59,7 @@
*/
declare var JSDialog: any;
+declare var app: any;
// TODO: remove this hack
var lastClickHelperRow: string | number = -1;
@@ -471,7 +472,7 @@ class TreeViewControl {
const iconId = this.getCellIconId(entry.columns[index]);
L.DomUtil.addClass(icon, iconId + 'img');
const iconName = builder._createIconURL(iconId, true);
- L.LOUtil.setImage(icon, iconName, builder.map);
+ app.LOUtil.setImage(icon, iconName, builder.map);
icon.tabIndex = -1;
icon.alt = ''; //In this case, it is advisable to use an empty alt tag for the icons, as the information of the function is available in text form
}
diff --git a/browser/src/core/Events.js b/browser/src/core/Events.js
index 9a670c9d9a759..c30962843a2f2 100644
--- a/browser/src/core/Events.js
+++ b/browser/src/core/Events.js
@@ -1,4 +1,5 @@
/* -*- js-indent-level: 8 -*- */
+/* global app */
/*
* L.Evented is a base class that Leaflet classes inherit from to handle custom events.
*/
@@ -17,7 +18,7 @@ L.Evented = L.Class.extend({
} else {
// types can be a string of space-separated words
- types = L.Util.splitWords(types);
+ types = app.util.splitWords(types);
for (var i = 0, len = types.length; i < len; i++) {
this._on(types[i], fn, context);
@@ -39,7 +40,7 @@ L.Evented = L.Class.extend({
}
} else {
- types = L.Util.splitWords(types);
+ types = app.util.splitWords(types);
for (var i = 0, len = types.length; i < len; i++) {
this._off(types[i], fn, context);
@@ -53,7 +54,7 @@ L.Evented = L.Class.extend({
_on: function (type, fn, context) {
var events = this._events = this._events || {},
- contextId = context && context !== this && L.stamp(context);
+ contextId = context && context !== this && app.util.stamp(context);
if (contextId) {
// store listeners with custom context in a separate hash (if it has an id);
@@ -62,7 +63,7 @@ L.Evented = L.Class.extend({
var indexKey = type + '_idx',
indexLenKey = type + '_len',
typeIndex = events[indexKey] = events[indexKey] || {},
- id = L.stamp(fn) + '_' + contextId;
+ id = app.util.stamp(fn) + '_' + contextId;
if (!typeIndex[id]) {
typeIndex[id] = {fn: fn, ctx: context};
@@ -95,11 +96,11 @@ L.Evented = L.Class.extend({
return;
}
- var contextId = context && context !== this && L.stamp(context),
+ var contextId = context && context !== this && app.util.stamp(context),
listeners, i, len, listener, id;
if (contextId) {
- id = L.stamp(fn) + '_' + contextId;
+ id = app.util.stamp(fn) + '_' + contextId;
listeners = events[indexKey];
if (listeners && listeners[id]) {
@@ -124,7 +125,7 @@ L.Evented = L.Class.extend({
// set the removed listener to noop so that's not called if remove happens in fire
if (listener) {
- listener.fn = L.Util.falseFn;
+ listener.fn = app.util.falseFn;
}
},
@@ -199,13 +200,13 @@ L.Evented = L.Class.extend({
// adds a parent to propagate events to (when you fire with true as a 3rd argument)
addEventParent: function (obj) {
this._eventParents = this._eventParents || {};
- this._eventParents[L.stamp(obj)] = obj;
+ this._eventParents[app.util.stamp(obj)] = obj;
return this;
},
removeEventParent: function (obj) {
if (this._eventParents) {
- delete this._eventParents[L.stamp(obj)];
+ delete this._eventParents[app.util.stamp(obj)];
}
return this;
},
diff --git a/browser/src/core/LOUtil.js b/browser/src/core/LOUtil.js
deleted file mode 100644
index 4eca63b765586..0000000000000
--- a/browser/src/core/LOUtil.js
+++ /dev/null
@@ -1,328 +0,0 @@
-/* -*- js-indent-level: 8 -*- */
-/*
- * L.LOUtil contains various LO related utility functions used throughout the code
- */
-
-L.LOUtil = {
- // Based on core.git's colordata.hxx: COL_AUTHOR1_DARK...COL_AUTHOR9_DARK
- // consisting of arrays of RGB values
- // Maybe move the color logic to separate file when it becomes complex
- darkColors: [
- [198, 146, 0],
- [6, 70, 162],
- [87, 157, 28],
- [105, 43, 157],
- [197, 0, 11],
- [0, 128, 128],
- [140, 132, 0],
- [53, 85, 107],
- [209, 118, 0]
- ],
-
- // https://stackoverflow.com/a/32726412
- onRemoveHTMLElement: function(element, onDetachCallback) {
- var observer = new MutationObserver(function () {
- function isDetached(el) {
- return !el.closest('html');
- }
-
- if (isDetached(element)) {
- onDetachCallback();
- observer.disconnect();
- }
- });
-
- observer.observe(document, {
- childList: true,
- subtree: true
- });
- },
-
- startSpinner: function (spinnerCanvas, spinnerSpeed) {
- var spinnerInterval;
- spinnerCanvas.width = 50;
- spinnerCanvas.height = 50;
-
- var context = spinnerCanvas.getContext('2d');
- context.lineWidth = 8;
- context.strokeStyle = 'grey';
- var x = spinnerCanvas.width / 2;
- var y = spinnerCanvas.height / 2;
- var radius = y - context.lineWidth / 2;
- spinnerInterval = setInterval(function() {
- context.clearRect(0, 0, x * 2, y * 2);
- // Move to center
- context.translate(x, y);
- context.rotate(spinnerSpeed * Math.PI / 180);
- context.translate(-x, -y);
- context.beginPath();
- context.arc(x, y, radius, 0, Math.PI * 1.3);
- context.stroke();
- }, 30);
-
- return spinnerInterval;
- },
-
- getViewIdColor: function(viewId) {
- var color = this.darkColors[(viewId + 1) % this.darkColors.length];
- return (color[2] | (color[1] << 8) | (color[0] << 16));
- },
-
- rgbToHex: function(color) {
- return '#' + ('000000' + color.toString(16)).slice(-6);
- },
-
- stringToBounds: function(bounds) {
- var numbers = bounds.match(/\d+/g);
- var topLeft = L.point(parseInt(numbers[0]), parseInt(numbers[1]));
- var bottomRight = topLeft.add(L.point(parseInt(numbers[2]), parseInt(numbers[3])));
- return L.bounds(topLeft, bottomRight);
- },
-
- stringToRectangles: function(strRect) {
- var matches = strRect.match(/\d+/g);
- var rectangles = [];
- if (matches !== null) {
- for (var itMatch = 0; itMatch < matches.length; itMatch += 4) {
- var topLeft = L.point(parseInt(matches[itMatch]), parseInt(matches[itMatch + 1]));
- var size = L.point(parseInt(matches[itMatch + 2]), parseInt(matches[itMatch + 3]));
- var topRight = topLeft.add(L.point(size.x, 0));
- var bottomLeft = topLeft.add(L.point(0, size.y));
- var bottomRight = topLeft.add(size);
- rectangles.push([bottomLeft, bottomRight, topLeft, topRight]);
- }
- }
- return rectangles;
- },
-
- // Some items will only present in dark mode so we will not check errors for those in other mode
- onlydarkModeItems : ['invertbackground'],
-
- // Common images used in all modes, so the default one will be used.
- commonItems: ['serverauditok', 'serverauditerror'],
-
- // Helper function to strip '.svg' suffix and 'lc_' prefix
- stripName: function(name) {
- // Remove the '.svg' suffix
- var strippedName = name.replace(/\.svg$/, '');
-
- // Remove the 'lc_' prefix if it exists
- if (strippedName.startsWith('lc_')) {
- strippedName = strippedName.substring(3);
- }
-
- return strippedName;
- },
-
- isDarkModeItem: function(name) {
- var strippedName = this.stripName(name);
-
- // Check if the stripped name is in the onlydarkModeItems array
- return this.onlydarkModeItems.includes(strippedName);
- },
-
- isCommonForAllMode: function(name) {
- var strippedName = this.stripName(name);
-
- // Check if the stripped name is in the commonItems array
- return this.commonItems.includes(strippedName);
- },
-
- /// unwind things to get a good absolute URL
- getURL: function(path) {
- if (path === '')
- return '';
- if (window.host === '' && window.serviceRoot === '')
- return path; // mobile app
-
- var url = window.makeHttpUrl('/browser/' + window.versionPath);
- if (path.substr(0,1) !== '/')
- url += '/';
- url += path;
- return url;
- },
- setImage: function(img, name, map) {
- var setupIcon = function () {
- img.src = this.getImageURL(name);
- this.checkIfImageExists(img);
- }.bind(this);
- setupIcon();
-
- map.on('themechanged', setupIcon, this);
- },
- setUserImage: function(img, map, viewId) {
- // set avatar image if it exist in user extract info
- var defaultImage = L.LOUtil.getImageURL('user.svg');
- var viewInfo = map._viewInfo[viewId];
- if (
- viewInfo !== undefined
- && viewInfo.userextrainfo !== undefined
- && viewInfo.userextrainfo.avatar !== undefined
- ) {
- // set user avatar
- img.src = viewInfo.userextrainfo.avatar;
- // Track if error event is already bound to this image
- img.addEventListener('error', function () {
- img.src = defaultImage;
- this.checkIfImageExists(img, true);
- }.bind(this), {once:true});
- return;
- }
- img.src = defaultImage;
- this.checkIfImageExists(img, true);
- },
-
- getImageURL: function(imgName) {
- var defaultImageURL = this.getURL('images/' + imgName);
-
- // Check if the image name is in the commonItems list and return the normal image path
- if (this.isCommonForAllMode(imgName)) {
- return defaultImageURL;
- }
-
- if (window.prefs.getBoolean('darkTheme')) {
- return this.getURL('images/dark/' + imgName);
- }
-
- var dummyEmptyImg = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNkYAAAAAYAAjCB0C8AAAAASUVORK5CYII=';
- defaultImageURL = this.isDarkModeItem(imgName) ? dummyEmptyImg : defaultImageURL;
- return defaultImageURL;
- },
-
- checkIfImageExists: function (imageElement, imageIsLayoutCritical) {
- imageElement.addEventListener('error', function (e) {
- if (e.loUtilProcessed) {
- return;
- }
-
- if (imageElement.src && imageElement.src.includes('/images/branding/dark/')) {
- imageElement.src = imageElement.src.replace('/images/branding/dark/', '/images/dark/');
- e.loUtilProcessed = true;
- return;
- }
- if (imageElement.src && (imageElement.src.includes('/images/dark/') || imageElement.src.includes('/images/branding/'))) {
- imageElement.src = imageElement.src.replace('/images/dark/', '/images/');
- imageElement.src = imageElement.src.replace('/images/branding/', '/images/');
- e.loUtilProcessed = true;
- return;
- }
-
- if (imageIsLayoutCritical) {
- imageElement.src = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNkYAAAAAYAAjCB0C8AAAAASUVORK5CYII=';
- // We cannot set visibility: hidden because that would hide other attributes of the image, e.g. its border
- e.loUtilProcessed = true;
- return;
- }
-
- imageElement.style.display = 'none';
- e.loUtilProcessed = true;
- });
- },
- /// oldFileName = Example.odt, suffix = new
- /// returns: Example_new.odt
- generateNewFileName: function(oldFileName, suffix) {
- var idx = oldFileName.lastIndexOf('.');
- return oldFileName.substring(0, idx) + suffix + oldFileName.substring(idx);
- },
-
- commandWithoutIcon: [
- 'InsertPageHeader',
- 'InsertPageFooter',
- 'FLD_COL_NUMBER',
- 'MTR_FLD_COL_SPACING',
- 'rows',
- 'cols',
- 'None'
- ],
-
- existsIconForCommand: function(command, docType) {
- var commandName = command.startsWith('.uno:') ? command.substring('.uno:'.length) : command;
- var res = !this.commandWithoutIcon.find(function (el) {
- return el.startsWith(commandName);
- });
- if (commandName.indexOf('?')!== -1) {
- if (commandName.indexOf('SpellCheckIgnore') !== -1 || commandName.indexOf('SpellCheckIgnoreAll') !== -1)
- return true;
-
- if ((docType === 'spreadsheet' || docType === 'presentation') &&
- commandName.indexOf('LanguageStatus') !== -1)
- return true;
-
- if (commandName === 'LanguageStatus?Language:string=Current_LANGUAGE_NONE' ||
- commandName === 'LanguageStatus?Language:string=Current_RESET_LANGUAGES' ||
- commandName === 'LanguageStatus?Language:string=Paragraph_LANGUAGE_NONE' ||
- commandName === 'LanguageStatus?Language:string=Paragraph_RESET_LANGUAGES')
- return true;
-
- return false;
- }
- return res;
- },
-
- /// Searching in JSON trees for data with a given field
- findItemWithAttributeRecursive: function(node, idName, idValue) {
- var found = null;
- if (node[idName] === idValue)
- return node;
- if (node.children)
- {
- for (var i = 0; !found && i < node.children.length; i++)
- found = L.LOUtil.findItemWithAttributeRecursive(node.children[i], idName, idValue);
- }
- return found;
- },
-
- /// Searching in JSON trees for an identifier and return the index in parent
- findIndexInParentByAttribute: function(node, idName, idValue) {
- if (node.children)
- {
- for (var i = 0; i < node.children.length; i++)
- if (node.children[i][idName] === idValue)
- return i;
- }
- return -1;
- },
-
- _doRectanglesIntersect: function (rectangle1, rectangle2) { // Format: (x, y, w, h).
- // Don't use equality in comparison, that's not an intersection.
- if (Math.abs((rectangle1[0] + rectangle1[2] * 0.5) - (rectangle2[0] + rectangle2[2] * 0.5)) < rectangle1[2] + rectangle2[2]) {
- if (Math.abs((rectangle1[1] + rectangle1[3] * 0.5) - (rectangle2[1] + rectangle2[3] * 0.5)) < rectangle1[3] + rectangle2[3])
- return true;
- else
- return false;
- }
- else
- return false;
- },
-
- // Returns the intersecting area of 2 rectangles. Rectangle format: (x, y, w, h). Return format is the same or null.
- _getIntersectionRectangle: function (rectangle1, rectangle2) {
- if (this._doRectanglesIntersect(rectangle1, rectangle2)) {
- var x = (rectangle1[0] > rectangle2[0] ? rectangle1[0]: rectangle2[0]);
- var y = (rectangle1[1] > rectangle2[1] ? rectangle1[1]: rectangle2[1]);
- var w = (rectangle1[0] + rectangle1[2] < rectangle2[0] + rectangle2[2] ? rectangle1[0] + rectangle1[2] - x: rectangle2[0] + rectangle2[2] - x);
- var h = (rectangle1[1] + rectangle1[3] < rectangle2[1] + rectangle2[3] ? rectangle1[1] + rectangle1[3] - y: rectangle2[1] + rectangle2[3] - y);
-
- return [x, y, w, h];
- }
- else
- return null;
- },
-
- getFileExtension: function (map) {
- var filename = map['wopi'].BaseFileName;
- return filename.substring(filename.lastIndexOf('.') + 1);
- },
-
- isFileODF: function (map) {
- var ext = this.getFileExtension(map);
- return ext === 'odt' || ext === 'ods' || ext === 'odp' || ext == 'odg';
- },
-
- containsDOMRect: function (viewRect, rect) {
- return (rect.top >= viewRect.top &&
- rect.right <= viewRect.right &&
- rect.bottom <= viewRect.bottom &&
- rect.left >= viewRect.left)
- }
-};
diff --git a/browser/src/core/Matrix.js b/browser/src/core/Matrix.js
deleted file mode 100644
index bd1612a285a1e..0000000000000
--- a/browser/src/core/Matrix.js
+++ /dev/null
@@ -1,206 +0,0 @@
-/* -*- js-indent-level: 8 -*- */
-
-/**
- * @class L.Matrix
- *
- * @param {Number} a
- * @param {Number} b
- * @param {Number} c
- * @param {Number} d
- * @param {Number} e
- * @param {Number} f
- */
-L.Matrix = function(a, b, c, d, e, f) {
-
- /**
- * @type {Array.}
- */
- this._matrix = [a, b, c, d, e, f];
-};
-
-
-L.Matrix.prototype = {
-
-
- /**
- * @param {L.Point} point
- * @return {L.Point}
- */
- transform: function(point) {
- return this._transform(point.clone());
- },
-
-
- /**
- * Destructive
- *
- * [ x ] = [ a b tx ] [ x ] = [ a * x + b * y + tx ]
- * [ y ] = [ c d ty ] [ y ] = [ c * x + d * y + ty ]
- *
- * @param {L.Point} point
- * @return {L.Point}
- */
- _transform: function(point) {
- var matrix = this._matrix;
- var x = point.x, y = point.y;
- point.x = matrix[0] * x + matrix[1] * y + matrix[4];
- point.y = matrix[2] * x + matrix[3] * y + matrix[5];
- return point;
- },
-
-
- /**
- * @param {L.Point} point
- * @return {L.Point}
- */
- untransform: function (point) {
- var matrix = this._matrix;
- return new L.Point(
- (point.x / matrix[0] - matrix[4]) / matrix[0],
- (point.y / matrix[2] - matrix[5]) / matrix[2]
- );
- },
-
-
- /**
- * @return {L.Matrix}
- */
- clone: function() {
- var matrix = this._matrix;
- return new L.Matrix(
- matrix[0], matrix[1], matrix[2],
- matrix[3], matrix[4], matrix[5]
- );
- },
-
-
- /**
- * @param {L.Point=|Number=} translate
- * @return {L.Matrix|L.Point}
- */
- translate: function(translate) {
- if (translate === undefined) {
- return new L.Point(this._matrix[4], this._matrix[5]);
- }
-
- var translateX, translateY;
- if (typeof translate === 'number') {
- translateX = translateY = translate;
- } else {
- translateX = translate.x;
- translateY = translate.y;
- }
-
- return this._add(1, 0, 0, 1, translateX, translateY);
- },
-
-
- /**
- * @param {L.Point=|Number=} scale
- * @return {L.Matrix|L.Point}
- */
- scale: function(scale, origin) {
- if (scale === undefined) {
- return new L.Point(this._matrix[0], this._matrix[3]);
- }
-
- var scaleX, scaleY;
- origin = origin || L.point(0, 0);
- if (typeof scale === 'number') {
- scaleX = scaleY = scale;
- } else {
- scaleX = scale.x;
- scaleY = scale.y;
- }
-
- return this
- ._add(scaleX, 0, 0, scaleY, origin.x, origin.y)
- ._add(1, 0, 0, 1, -origin.x, -origin.y);
- },
-
-
- /**
- * m00 m01 x - m00 * x - m01 * y
- * m10 m11 y - m10 * x - m11 * y
- * @param {Number} angle
- * @param {L.Point=} origin
- * @return {L.Matrix}
- */
- rotate: function(angle, origin) {
- var cos = Math.cos(angle);
- var sin = Math.sin(angle);
-
- origin = origin || new L.Point(0, 0);
-
- return this
- ._add(cos, sin, -sin, cos, origin.x, origin.y)
- ._add(1, 0, 0, 1, -origin.x, -origin.y);
- },
-
-
- /**
- * Invert rotation
- * @return {L.Matrix}
- */
- flip: function() {
- this._matrix[1] *= -1;
- this._matrix[2] *= -1;
- return this;
- },
-
-
- /**
- * @param {Number|L.Matrix} a
- * @param {Number} b
- * @param {Number} c
- * @param {Number} d
- * @param {Number} e
- * @param {Number} f
- */
- _add: function(a, b, c, d, e, f) {
- var result = [[], [], []];
- var src = this._matrix;
- var m = [
- [src[0], src[2], src[4]],
- [src[1], src[3], src[5]],
- [ 0, 0, 1]
- ];
- var other = [
- [a, c, e],
- [b, d, f],
- [0, 0, 1]
- ], val;
-
-
- if (a && a instanceof L.Matrix) {
- src = a._matrix;
- other = [
- [src[0], src[2], src[4]],
- [src[1], src[3], src[5]],
- [ 0, 0, 1]];
- }
-
- for (var i = 0; i < 3; i++) {
- for (var j = 0; j < 3; j++) {
- val = 0;
- for (var k = 0; k < 3; k++) {
- val += m[i][k] * other[k][j];
- }
- result[i][j] = val;
- }
- }
-
- this._matrix = [
- result[0][0], result[1][0], result[0][1],
- result[1][1], result[0][2], result[1][2]
- ];
- return this;
- }
-
-
-};
-
-
-L.matrix = function(a, b, c, d, e, f) {
- return new L.Matrix(a, b, c, d, e, f);
-};
diff --git a/browser/src/core/Rectangle.ts b/browser/src/core/Rectangle.ts
deleted file mode 100644
index aeb5a7298d45f..0000000000000
--- a/browser/src/core/Rectangle.ts
+++ /dev/null
@@ -1,265 +0,0 @@
-/* -*- js-indent-level: 8 -*- */
-/*
- * Copyright the Collabora Online contributors.
- *
- * SPDX-License-Identifier: MPL-2.0
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/.
- */
-declare var L: any;
-
-namespace cool {
-
-/**
- * Represents a rectangle object which works with core pixels.
- * x1 and y1 should always <= x2 and y2. In other words width >= 0 && height >= 0 is a precondition.
- * This class doesn't check for above conditions. There is a isValid function for use when needed.
- */
-export class Rectangle {
- private x1: number;
- private y1: number;
- private width: number;
- private height: number;
-
- constructor (x: number, y: number, width: number, height: number) {
- this.x1 = x;
- this.y1 = y;
- this.width = width;
- this.height = height;
- }
-
- // convenience private getters
-
- private get x2(): number {
- return this.x1 + this.width;
- }
-
- private get y2(): number {
- return this.y1 + this.height;
- }
-
- private get area(): number {
- return this.width * this.height;
- }
-
- // Rounded coordinates private getters
-
- private get rx1(): number {
- return Math.round(this.x1);
- }
-
- private get ry1(): number {
- return Math.round(this.y1);
- }
-
- private get rx2(): number {
- return Math.round(this.x2);
- }
-
- private get ry2(): number {
- return Math.round(this.y2);
- }
-
- private get rwidth(): number {
- return this.rx2 - this.rx1;
- }
-
- private get rheight(): number {
- return this.ry2 - this.ry1;
- }
-
- private get rarea(): number {
- return this.rwidth * this.rheight;
- }
-
- public isValid(): boolean {
- if (this.x1 <= this.x2 && this.y1 <= this.y2)
- return true;
- return false;
- }
-
- public clone(): Rectangle {
- return new Rectangle(this.x1, this.x2, this.width, this.height);
- }
-
- public containsPoint (x: number, y: number): boolean {
- if (x >= this.x1 && x <= this.x2
- && y >= this.y1 && y <= this.y2)
- return true;
-
- return false;
- }
-
- public containsPixel (px: number, py: number): boolean {
- if (px >= this.rx1 && px <= this.rx2
- && py >= this.ry1 && py <= this.ry2)
- return true;
-
- return false;
- }
-
- public containsXOrdinate (ox: number): boolean {
- if (ox >= this.x1 && ox <= this.x2)
- return true;
-
- return false;
- }
-
- public containsYOrdinate (oy: number): boolean {
- if (oy >= this.y1 && oy <= this.y2)
- return true;
-
- return false;
- }
-
- public containsPixelOrdinateX (ox: number): boolean {
- if (ox >= this.rx1 && ox <= this.rx2)
- return true;
-
- return false;
- }
-
- public containsPixelOrdinateY (oy: number): boolean {
- if (oy >= this.ry1 && oy <= this.ry2)
- return true;
-
- return false;
- }
-
- /// Sets x1 of the rectangle without changing x2.
- public setX1 (x1: number): void {
- this.width += (this.x1 - x1);
- this.x1 = x1;
- }
-
- /// Sets x2 of the rectangle without changing x1.
- public setX2 (x2: number): void {
- this.width = x2 - this.x1;
- }
-
- /// Sets y1 of the rectangle without changing y2.
- public setY1 (y1: number): void {
- this.height += (this.y1 - y1);
- this.y1 = y1;
- }
-
- /// Sets y2 of the rectangle without changing y1.
- public setY2 (y2: number): void {
- this.height = y2 - this.y1;
- }
-
- /// Sets width keeping x1 constant.
- public setWidth (width: number): void {
- this.width = width;
- }
-
- /// Sets height keeping y1 constant.
- public setHeight (height: number): void {
- this.height = height;
- }
-
- /// Sets area by either keeping height or width as constant.
- public setArea (area: number, preserveHeight: boolean): void {
- if (!preserveHeight) { //preserve width
- const height = area / this.width;
- this.setHeight(height);
- }
- else { // preserve height
- const width = area / this.height;
- this.setWidth(width);
- }
- }
-
- /// Moves the whole rectangle by (dx, dy) by preserving width and height.
- public moveBy (dx: number, dy: number): void {
- this.x1 += dx;
- this.y1 += dy;
- }
-
- /**
- * Moves the rectangle to (x, y) as its new x1, y1 without changing
- * its size.
- */
- public moveTo (x: number, y: number): void {
- this.x1 = x;
- this.y1 = y;
- }
-
- // TODO: Following methods could be replaced with js getters
- // but we need to change their users to access getters.
-
- public getX1(): number {
- return this.x1;
- }
-
- public getX2(): number {
- return this.x2;
- }
-
- public getY1(): number {
- return this.y1;
- }
-
- public getY2(): number {
- return this.y2;
- }
-
- public getWidth(): number {
- return this.width;
- }
-
- public getHeight(): number {
- return this.height;
- }
-
- public getArea(): number {
- return this.area;
- }
-
- public getCenter(): number[] {
- return [(this.x2 + this.x1) / 2, (this.y2 + this.y1) / 2];
- }
-
- public getPxX1(): number {
- return this.rx1;
- }
-
- public getPxX2(): number {
- return this.rx2;
- }
-
- public getPxY1(): number {
- return this.ry1;
- }
-
- public getPxY2(): number {
- return this.ry2;
- }
-
- public getPxWidth(): number {
- return this.rwidth;
- }
-
- public getPxHeight(): number {
- return this.rheight;
- }
-
- public getPxArea(): number {
- return this.rarea;
- }
-
- public getPxCenter(): number[] {
- return [Math.round((this.rx2 + this.rx1) / 2), Math.round((this.ry2 + this.ry1) / 2)];
- }
-}
-
-export function createRectangle(x: number, y: number, width: number, height: number): Rectangle {
- return new Rectangle(x, y, width, height);
-}
-
-}
-
-L.LOUtil.Rectangle = cool.Rectangle;
-L.LOUtil.createRectangle = cool.createRectangle;
diff --git a/browser/src/core/Socket.js b/browser/src/core/Socket.js
index 196ac58bf63cd..730c79f9335ba 100644
--- a/browser/src/core/Socket.js
+++ b/browser/src/core/Socket.js
@@ -1215,7 +1215,7 @@ app.definitions.Socket = L.Class.extend({
this._map.fire('infobar',
{
msg: textMsg,
- action: L.Util.getProduct(),
+ action: app.util.getProduct(),
actionLabel: errorMessages.infoandsupport
});
}
@@ -1431,7 +1431,7 @@ app.definitions.Socket = L.Class.extend({
callbackList.push({ id: 'save-to-new-file', func_: function() {
var filename = this._map['wopi'].BaseFileName;
if (filename) {
- filename = L.LOUtil.generateNewFileName(filename, '_new');
+ filename = app.LOUtil.generateNewFileName(filename, '_new');
this._map.saveAs(filename);
}
}.bind(this)});
@@ -1617,7 +1617,7 @@ app.definitions.Socket = L.Class.extend({
_onJSDialog: function(textMsg, callback) {
var msgData = JSON.parse(textMsg.substring('jsdialog:'.length + 1));
- if (msgData.children && !L.Util.isArray(msgData.children)) {
+ if (msgData.children && !app.util.isArray(msgData.children)) {
window.app.console.warn('_onJSDialogMsg: The children\'s data should be created of array type');
return;
}
diff --git a/browser/src/core/Util.js b/browser/src/core/Util.js
index 2be44e2f1a0fc..bc6b64626644a 100644
--- a/browser/src/core/Util.js
+++ b/browser/src/core/Util.js
@@ -3,8 +3,6 @@
* L.Util contains various utility functions used throughout Leaflet code.
*/
-/* global brandProductFAQURL */
-
L.Util = {
// extend an object with properties of one or more other objects
extend: function (dest) {
@@ -43,93 +41,6 @@ L.Util = {
};
},
- // return unique ID of an object
- stamp: function (obj) {
- /*eslint-disable */
- obj._leaflet_id = obj._leaflet_id || ++L.Util.lastId;
- return obj._leaflet_id;
- /*eslint-enable */
- },
-
- lastId: 0,
-
- // return a function that won't be called more often than the given interval
- throttle: function (fn, time, context) {
- var lock, args, wrapperFn, later;
-
- later = function () {
- // reset lock and call if queued
- lock = false;
- if (args) {
- wrapperFn.apply(context, args);
- args = false;
- }
- };
-
- wrapperFn = function () {
- if (lock) {
- // called too soon, queue to call later
- args = arguments;
-
- } else {
- // call and lock until later
- fn.apply(context, arguments);
- setTimeout(later, time);
- lock = true;
- }
- };
-
- return wrapperFn;
- },
-
- // wrap the given number to lie within a certain range (used for wrapping longitude)
- wrapNum: function (x, range, includeMax) {
- var max = range[1],
- min = range[0],
- d = max - min;
- return x === max && includeMax ? x : ((x - min) % d + d) % d + min;
- },
-
- // do nothing (used as a noop throughout the code)
- falseFn: function () { return false; },
-
- // round a given number to a given precision
- formatNum: function (num, digits) {
- var pow = Math.pow(10, digits || 5);
- return Math.round(num * pow) / pow;
- },
-
- // removes given prefix and suffix from the string if exists
- // if suffix is not specified prefix is trimmed from both end of string
- // trim whitespace from both sides of a string if prefix and suffix are not given
- trim: function (str, prefix, suffix) {
- if (!prefix)
- return str.trim ? str.trim() : str.replace(/^\s+|\s+$/g, '');
- var result = this.trimStart(str, prefix);
- result = this.trimEnd(result, suffix);
- return result;
- },
-
- // removes prefix from string if string starts with that prefix
- trimStart: function (str, prefix) {
- if (str.indexOf(prefix) === 0)
- return str.substring(prefix.length);
- return str;
- },
-
- // removes suffix from string if string ends with that suffix
- trimEnd: function (str, suffix) {
- var suffixIndex = str.lastIndexOf(suffix);
- if (suffixIndex !== -1 && (str.length - suffix.length === suffixIndex))
- return str.substring(0, suffixIndex);
- return str;
- },
-
- // split a string into words
- splitWords: function (str) {
- return L.Util.trim(str).split(/\s+/);
- },
-
// set options to an object, inheriting parent's options as well
setOptions: function (obj, options) {
if (!Object.prototype.hasOwnProperty.call(obj, 'options')) {
@@ -141,162 +52,9 @@ L.Util = {
return obj.options;
},
- round: function(x, e) {
- if (!e) {
- return Math.round(x);
- }
- var f = 1.0/e;
- return Math.round(x * f) * e;
- },
-
- // super-simple templating facility, used for TileLayer URLs
- template: function (str, data) {
- return str.replace(L.Util.templateRe, function (str, key) {
- var value = data[key];
-
- if (value === undefined) {
- throw new Error('No value provided for variable ' + str);
-
- } else if (typeof value === 'function') {
- value = value(data);
- }
- return value;
- });
- },
-
- templateRe: /\{ *([\w_]+) *\}/g,
-
- isArray: Array.isArray || function (obj) {
- return (Object.prototype.toString.call(obj) === '[object Array]');
- },
-
- // minimal image URI, set to an image when disposing to flush memory
- emptyImageUrl: 'data:image/gif;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs=',
-
- toggleFullScreen: function() {
- if (!document.fullscreenElement &&
- !document.mozFullscreenElement &&
- !document.msFullscreenElement &&
- !document.webkitFullscreenElement) {
- if (document.documentElement.requestFullscreen) {
- document.documentElement.requestFullscreen();
- } else if (document.documentElement.msRequestFullscreen) {
- document.documentElement.msRequestFullscreen();
- } else if (document.documentElement.mozRequestFullScreen) {
- document.documentElement.mozRequestFullScreen();
- } else if (document.documentElement.webkitRequestFullscreen) {
- document.documentElement.webkitRequestFullscreen(Element.ALLOW_KEYBOARD_INPUT);
- }
- } else if (document.exitFullscreen) {
- document.exitFullscreen();
- } else if (document.msExitFullscreen) {
- document.msExitFullscreen();
- } else if (document.mozCancelFullScreen) {
- document.mozCancelFullScreen();
- } else if (document.webkitExitFullscreen) {
- document.webkitExitFullscreen();
- }
- },
-
- isEmpty: function(o) {
- return !(o && o.length);
- },
-
- mm100thToInch: function(mm) {
- return mm / 2540;
- },
-
- getTextWidth: function(text, font) {
- var canvas = L.Util.getTextWidth._canvas || (L.Util.getTextWidth._canvas = document.createElement('canvas'));
- var context = canvas.getContext('2d');
- context.font = font;
- var metrics = context.measureText(text);
- return Math.floor(metrics.width);
- },
-
- getProduct: function () {
- var brandFAQURL = (typeof brandProductFAQURL !== 'undefined') ?
- brandProductFAQURL : 'https://collaboraonline.github.io/post/faq/';
- if (window.feedbackUrl && window.buyProductUrl) {
- var integratorUrl = encodeURIComponent(window.buyProductUrl);
- brandFAQURL = window.feedbackUrl;
- brandFAQURL = brandFAQURL.substring(0, brandFAQURL.lastIndexOf('/')) +
- '/product.html?integrator='+ integratorUrl;
- }
- return brandFAQURL;
- },
-
- replaceCtrlAltInMac: function(msg) {
- if (L.Browser.mac) {
- var ctrl = /Ctrl/g;
- var alt = /Alt/g;
- if (String.locale.startsWith('de') || String.locale.startsWith('dsb') || String.locale.startsWith('hsb')) {
- ctrl = /Strg/g;
- }
- if (String.locale.startsWith('lt')) {
- ctrl = /Vald/g;
- }
- if (String.locale.startsWith('sl')) {
- ctrl = /Krmilka/gi;
- alt = /Izmenjalka/gi;
- }
- return msg.replace(ctrl, '⌘').replace(alt, '⌥');
- }
- return msg;
- },
- randomString: function(len) {
- var result = '';
- var ValidCharacters = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
- for (var i = 0; i < len; i++) {
- result += ValidCharacters.charAt(Math.floor(Math.random() * ValidCharacters.length));
- }
- return result;
- }
};
-(function () {
- // inspired by http://paulirish.com/2011/requestanimationframe-for-smart-animating/
-
- function getPrefixed(name) {
- return window['webkit' + name] || window['moz' + name] || window['ms' + name];
- }
-
- var lastTime = 0;
-
- // fallback for IE 7-8
- function timeoutDefer(fn) {
- var time = +new Date(),
- timeToCall = Math.max(0, 16 - (time - lastTime));
-
- lastTime = time + timeToCall;
- return window.setTimeout(fn, timeToCall);
- }
-
- var requestFn = window.requestAnimationFrame || getPrefixed('RequestAnimationFrame') || timeoutDefer,
- cancelFn = window.cancelAnimationFrame || getPrefixed('CancelAnimationFrame') ||
- getPrefixed('CancelRequestAnimationFrame') || function (id) { window.clearTimeout(id); };
-
-
- L.Util.requestAnimFrame = function (fn, context, immediate) {
- if (immediate && requestFn === timeoutDefer) {
- fn.call(context);
- } else {
- return requestFn.call(window, L.bind(fn, context));
- }
- };
-
- L.Util.cancelAnimFrame = function (id) {
- if (id) {
- cancelFn.call(window, id);
- }
- };
-
- // on IE11 Number.MAX_SAFE_INTEGER, Number.MIN_SAFE_INTEGER are not supported
- L.Util.MAX_SAFE_INTEGER = Math.pow(2, 53)-1;
- L.Util.MIN_SAFE_INTEGER = -L.Util.MAX_SAFE_INTEGER;
-})();
-
if (!String.prototype.startsWith) {
String.prototype.startsWith = function(searchString, position) {
position = position || 0;
@@ -323,10 +81,4 @@ if (!Number.MAX_SAFE_INTEGER) {
// shortcuts for most used utility functions
L.extend = L.Util.extend;
L.bind = L.Util.bind;
-L.stamp = L.Util.stamp;
L.setOptions = L.Util.setOptions;
-L.round = L.Util.round;
-L.toggleFullScreen = L.Util.toggleFullScreen;
-L.isEmpty = L.Util.isEmpty;
-L.mm100thToInch = L.Util.mm100thToInch;
-L.getTextWidth = L.Util.getTextWidth;
diff --git a/browser/src/docdispatcher.ts b/browser/src/docdispatcher.ts
index 9d201be2f3a7b..53ad28493baab 100644
--- a/browser/src/docdispatcher.ts
+++ b/browser/src/docdispatcher.ts
@@ -497,7 +497,7 @@ class Dispatcher {
};
this.actionsMap['fullscreen-drawing'] = () => {
- L.toggleFullScreen();
+ app.util.toggleFullScreen();
};
this.actionsMap['deletepage'] = function () {
diff --git a/browser/src/docstate.js b/browser/src/docstate.js
index c9a57170529bc..bb3187a88489d 100644
--- a/browser/src/docstate.js
+++ b/browser/src/docstate.js
@@ -36,6 +36,8 @@ window.app = {
twipsCorrection: 0.567 // There is a constant ratio between tiletwips and impress page twips. For now, this seems safe to use.
},
map: null, // Make map object a part of this.
+ util: null, // Attach the Util class.
+ LOUtil: null, // Attach the LOUtil class.
dispatcher: null, // A Dispatcher class instance is assigned to this.
twipsToPixels: 0, // Twips to pixels multiplier.
pixelsToTwips: 0, // Pixels to twips multiplier.
diff --git a/browser/src/dom/DomEvent.js b/browser/src/dom/DomEvent.js
index 55949cd0da9ec..ea15e71eaa1a0 100644
--- a/browser/src/dom/DomEvent.js
+++ b/browser/src/dom/DomEvent.js
@@ -1,4 +1,5 @@
/* -*- js-indent-level: 8 -*- */
+/* global app */
/*
* L.DomEvent contains functions for working with DOM events.
* Inspired by John Resig, Dean Edwards and YUI addEvent implementations.
@@ -15,7 +16,7 @@ L.DomEvent = {
this._on(obj, type, types[type], fn);
}
} else {
- types = L.Util.splitWords(types);
+ types = app.util.splitWords(types);
for (var i = 0, len = types.length; i < len; i++) {
this._on(obj, types[i], fn, context);
@@ -32,7 +33,7 @@ L.DomEvent = {
this._off(obj, type, types[type], fn);
}
} else {
- types = L.Util.splitWords(types);
+ types = app.util.splitWords(types);
for (var i = 0, len = types.length; i < len; i++) {
this._off(obj, types[i], fn, context);
@@ -43,7 +44,7 @@ L.DomEvent = {
},
_on: function (obj, type, fn, context) {
- var id = type + L.stamp(fn) + (context ? '_' + L.stamp(context) : '');
+ var id = type + app.util.stamp(fn) + (context ? '_' + app.util.stamp(context) : '');
if (obj[eventsKey] && obj[eventsKey][id]) { return this; }
@@ -98,7 +99,7 @@ L.DomEvent = {
_off: function (obj, type, fn, context) {
- var id = type + L.stamp(fn) + (context ? '_' + L.stamp(context) : ''),
+ var id = type + app.util.stamp(fn) + (context ? '_' + app.util.stamp(context) : ''),
handler = obj[eventsKey] && obj[eventsKey][id];
if (!handler) { return this; }
diff --git a/browser/src/dom/DomUtil.js b/browser/src/dom/DomUtil.js
index 9b2419bd6a9b4..12e87d920f938 100644
--- a/browser/src/dom/DomUtil.js
+++ b/browser/src/dom/DomUtil.js
@@ -1,4 +1,5 @@
/* -*- js-indent-level: 8 -*- */
+/* global app */
/*
* L.DomUtil contains various utility functions for working with DOM.
*/
@@ -89,7 +90,7 @@ L.DomUtil = {
}
if (el.classList !== undefined) {
- var classes = L.Util.splitWords(name);
+ var classes = app.util.splitWords(name);
for (var i = 0, len = classes.length; i < len; i++) {
el.classList.add(classes[i]);
}
@@ -107,7 +108,7 @@ L.DomUtil = {
if (el.classList !== undefined) {
el.classList.remove(name);
} else {
- L.DomUtil.setClass(el, L.Util.trim((' ' + L.DomUtil.getClass(el) + ' ').replace(' ' + name + ' ', ' ')));
+ L.DomUtil.setClass(el, app.util.trim((' ' + L.DomUtil.getClass(el) + ' ').replace(' ' + name + ' ', ' ')));
}
},
diff --git a/browser/src/dom/Draggable.js b/browser/src/dom/Draggable.js
index 691c54585e8af..25ed284457422 100644
--- a/browser/src/dom/Draggable.js
+++ b/browser/src/dom/Draggable.js
@@ -1,4 +1,5 @@
/* -*- js-indent-level: 8 -*- */
+/* global app */
/*
* L.Draggable allows you to add dragging capabilities to any element. Supports mobile devices too.
*/
@@ -171,10 +172,10 @@ L.Draggable = L.Evented.extend({
this._moving = true;
- L.Util.cancelAnimFrame(this._animRequest);
+ app.util.cancelAnimFrame(this._animRequest);
this._lastEvent = e;
- this._animRequest = L.Util.requestAnimFrame(this._updatePosition, this, true, this._dragStartTarget);
+ this._animRequest = app.util.requestAnimFrame(this._updatePosition, this, true, this._dragStartTarget);
},
_updatePosition: function () {
@@ -203,7 +204,7 @@ L.Draggable = L.Evented.extend({
if (this._moved && this._moving) {
// ensure drag is not fired after dragend
- L.Util.cancelAnimFrame(this._animRequest);
+ app.util.cancelAnimFrame(this._animRequest);
this.fire('dragend', {
originalEvent: e,
diff --git a/browser/src/dom/PosAnimation.Timer.js b/browser/src/dom/PosAnimation.Timer.js
index 6a7957de44626..7c3dfd2a4be39 100644
--- a/browser/src/dom/PosAnimation.Timer.js
+++ b/browser/src/dom/PosAnimation.Timer.js
@@ -1,4 +1,5 @@
/* -*- js-indent-level: 8 -*- */
+/* global app */
/*
* L.PosAnimation fallback implementation that powers Leaflet pan animations
* in browsers that don't support CSS3 Transitions.
@@ -32,7 +33,7 @@ L.PosAnimation = L.DomUtil.TRANSITION ? L.PosAnimation : L.PosAnimation.extend({
_animate: function () {
// animation loop
- this._animId = L.Util.requestAnimFrame(this._animate, this);
+ this._animId = app.util.requestAnimFrame(this._animate, this);
this._step();
},
@@ -56,7 +57,7 @@ L.PosAnimation = L.DomUtil.TRANSITION ? L.PosAnimation : L.PosAnimation.extend({
},
_complete: function () {
- L.Util.cancelAnimFrame(this._animId);
+ app.util.cancelAnimFrame(this._animId);
this._inProgress = false;
this.fire('end');
diff --git a/browser/src/dom/PosAnimation.js b/browser/src/dom/PosAnimation.js
index b5ac8d1ec6053..6bf1addb9f714 100644
--- a/browser/src/dom/PosAnimation.js
+++ b/browser/src/dom/PosAnimation.js
@@ -1,4 +1,5 @@
/* -*- js-indent-level: 8 -*- */
+/* global app */
/*
* L.PosAnimation is used by Leaflet internally for pan animations.
*/
@@ -34,7 +35,7 @@ L.PosAnimation = L.Class.extend({
L.DomUtil.setPosition(el, newPos);
// toggle reflow, Chrome flickers for some reason if you don't do this
- L.Util.falseFn(el.offsetWidth);
+ app.util.falseFn(el.offsetWidth);
// there's no native way to track value updates of transitioned properties, so we imitate this
this._stepTimer = setInterval(L.bind(this._onStep, this), 50);
@@ -48,7 +49,7 @@ L.PosAnimation = L.Class.extend({
L.DomUtil.setPosition(this._el, this._getPos());
this._onTransitionEnd();
- L.Util.falseFn(this._el.offsetWidth); // force reflow in case we are about to start a new animation
+ app.util.falseFn(this._el.offsetWidth); // force reflow in case we are about to start a new animation
},
_onStep: function () {
diff --git a/browser/src/geo/LatLng.js b/browser/src/geo/LatLng.js
index 4fad29b55362b..62add5591fe5c 100644
--- a/browser/src/geo/LatLng.js
+++ b/browser/src/geo/LatLng.js
@@ -1,4 +1,5 @@
/* -*- js-indent-level: 8 -*- */
+/* global app */
/*
* L.LatLng represents a geographical point with latitude and longitude coordinates.
*/
@@ -31,8 +32,8 @@ L.LatLng.prototype = {
toString: function (precision) {
return 'LatLng(' +
- L.Util.formatNum(this.lat, precision) + ', ' +
- L.Util.formatNum(this.lng, precision) + ')';
+ app.util.formatNum(this.lat, precision) + ', ' +
+ app.util.formatNum(this.lng, precision) + ')';
},
distanceTo: function () {
@@ -52,7 +53,7 @@ L.latLng = function (a, b, c) {
if (a instanceof L.LatLng) {
return a;
}
- if (L.Util.isArray(a) && typeof a[0] !== 'object') {
+ if (app.util.isArray(a) && typeof a[0] !== 'object') {
if (a.length === 3) {
return new L.LatLng(a[0], a[1], a[2]);
}
diff --git a/browser/src/layer/FormFieldButtonLayer.js b/browser/src/layer/FormFieldButtonLayer.js
index 472c242388bab..e6fcad2d59b93 100644
--- a/browser/src/layer/FormFieldButtonLayer.js
+++ b/browser/src/layer/FormFieldButtonLayer.js
@@ -90,7 +90,7 @@ L.FormFieldButton = L.Layer.extend({
button.style.width = container.style.height;
var image = L.DomUtil.create('img', 'form-field-button-image', button);
- L.LOUtil.setImage(image, 'unfold.svg', this.map);
+ app.LOUtil.setImage(image, 'unfold.svg', this.map);
button.addEventListener('click', this._onClickDropDown);
// Stop propagation to the main document
diff --git a/browser/src/layer/Layer.js b/browser/src/layer/Layer.js
index 208da54b57e9e..8ede4119c5e12 100644
--- a/browser/src/layer/Layer.js
+++ b/browser/src/layer/Layer.js
@@ -1,4 +1,5 @@
/* -*- js-indent-level: 8 -*- */
+/* global app */
L.Layer = L.Evented.extend({
@@ -27,12 +28,12 @@ L.Layer = L.Evented.extend({
},
addInteractiveTarget: function (targetEl) {
- this._map._targets[L.stamp(targetEl)] = this;
+ this._map._targets[app.util.stamp(targetEl)] = this;
return this;
},
removeInteractiveTarget: function (targetEl) {
- delete this._map._targets[L.stamp(targetEl)];
+ delete this._map._targets[app.util.stamp(targetEl)];
return this;
},
@@ -59,7 +60,7 @@ L.Layer = L.Evented.extend({
L.Map.include({
addLayer: function (layer) {
- var id = L.stamp(layer);
+ var id = app.util.stamp(layer);
if (this._layers[id]) { return layer; }
this._layers[id] = layer;
@@ -75,7 +76,7 @@ L.Map.include({
},
removeLayer: function (layer) {
- var id = L.stamp(layer);
+ var id = app.util.stamp(layer);
if (!this._layers[id]) { return this; }
@@ -100,7 +101,7 @@ L.Map.include({
},
hasLayer: function (layer) {
- return !!layer && (L.stamp(layer) in this._layers);
+ return !!layer && (app.util.stamp(layer) in this._layers);
},
eachLayer: function (method, context) {
@@ -111,7 +112,7 @@ L.Map.include({
},
_addLayers: function (layers) {
- layers = layers ? (L.Util.isArray(layers) ? layers : [layers]) : [];
+ layers = layers ? (app.util.isArray(layers) ? layers : [layers]) : [];
for (var i = 0, len = layers.length; i < len; i++) {
this.addLayer(layers[i]);
@@ -120,13 +121,13 @@ L.Map.include({
_addZoomLimit: function (layer) {
if (isNaN(layer.options.maxZoom) || !isNaN(layer.options.minZoom)) {
- this._zoomBoundLayers[L.stamp(layer)] = layer;
+ this._zoomBoundLayers[app.util.stamp(layer)] = layer;
this._updateZoomLevels();
}
},
_removeZoomLimit: function (layer) {
- var id = L.stamp(layer);
+ var id = app.util.stamp(layer);
if (this._zoomBoundLayers[id]) {
delete this._zoomBoundLayers[id];
diff --git a/browser/src/layer/LayerGroup.js b/browser/src/layer/LayerGroup.js
index a43e0eee04cd4..afb3987c41c2f 100644
--- a/browser/src/layer/LayerGroup.js
+++ b/browser/src/layer/LayerGroup.js
@@ -1,4 +1,5 @@
/* -*- js-indent-level: 8 -*- */
+/* global app */
/*
* L.LayerGroup is a class to combine several layers into one so that
* you can manipulate the group (e.g. add/remove it) as one layer.
@@ -101,7 +102,7 @@ L.LayerGroup = L.Layer.extend({
},
getLayerId: function (layer) {
- return L.stamp(layer);
+ return app.util.stamp(layer);
}
});
diff --git a/browser/src/layer/marker/ProgressOverlay.js b/browser/src/layer/marker/ProgressOverlay.js
index 22e3cbf1d98fa..9c294c730345e 100644
--- a/browser/src/layer/marker/ProgressOverlay.js
+++ b/browser/src/layer/marker/ProgressOverlay.js
@@ -3,7 +3,7 @@
* L.ProgressOverlay is used to overlay progress images over the map.
*/
-/* global brandProductName $ */
+/* global app brandProductName $ */
L.ProgressOverlay = L.Layer.extend({
options: {
@@ -59,7 +59,7 @@ L.ProgressOverlay = L.Layer.extend({
showSpinner: function() {
L.DomUtil.get('document-container').appendChild(this._container);
- this._spinnerInterval = L.LOUtil.startSpinner(this._spinnerCanvas, this.options.spinnerSpeed);
+ this._spinnerInterval = app.LOUtil.startSpinner(this._spinnerCanvas, this.options.spinnerSpeed);
},
hideSpinner: function() {
diff --git a/browser/src/layer/tile/CalcTileLayer.js b/browser/src/layer/tile/CalcTileLayer.js
index 7f6ed386c97c5..c879054d1c4ea 100644
--- a/browser/src/layer/tile/CalcTileLayer.js
+++ b/browser/src/layer/tile/CalcTileLayer.js
@@ -1025,7 +1025,7 @@ L.CalcTileLayer = L.CanvasTileLayer.extend({
var bottomRightTwips = topLeftTwips.add(offset);
var boundsTwips = that._convertToTileTwipsSheetArea(new L.Bounds(topLeftTwips, bottomRightTwips));
- element = L.LOUtil.createRectangle(boundsTwips.min.x * ratio, boundsTwips.min.y * ratio, boundsTwips.getSize().x * ratio, boundsTwips.getSize().y * ratio);
+ element = app.LOUtil.createRectangle(boundsTwips.min.x * ratio, boundsTwips.min.y * ratio, boundsTwips.getSize().x * ratio, boundsTwips.getSize().y * ratio);
return element;
});
}
diff --git a/browser/src/layer/tile/CanvasTileLayer.js b/browser/src/layer/tile/CanvasTileLayer.js
index a7cdf57a22e3a..96b39fd885ae8 100644
--- a/browser/src/layer/tile/CanvasTileLayer.js
+++ b/browser/src/layer/tile/CanvasTileLayer.js
@@ -104,7 +104,7 @@ var CSelections = L.Class.extend({
if (!this._selection) {
if (!this._isOle) {
var fillColor = this._isView ?
- L.LOUtil.rgbToHex(this._map.getViewColor(this._viewId)) :
+ app.LOUtil.rgbToHex(this._map.getViewColor(this._viewId)) :
this._styleData.getPropValue('background-color');
var opacity = this._styleData.getFloatPropValue('opacity');
var weight = this._styleData.getFloatPropWithoutUnit('border-top-width');
@@ -298,7 +298,7 @@ L.TileSectionManager = L.Class.extend({
stopUpdates: function () {
if (this._updatesRunning) {
- L.Util.cancelAnimFrame(this._canvasRAF);
+ app.util.cancelAnimFrame(this._canvasRAF);
this.update();
this._updatesRunning = false;
return true;
@@ -347,7 +347,7 @@ L.TileSectionManager = L.Class.extend({
else {
var ratio = this._layer._tileSize / this._layer._tileHeightTwips;
var partHeightPixels = Math.round((this._layer._partHeightTwips + this._layer._spaceBetweenParts) * ratio);
- return L.LOUtil._doRectanglesIntersect(app.file.viewedRectangle.pToArray(), [coords.x, coords.y + partHeightPixels * coords.part, app.tile.size.pixels[0], app.tile.size.pixels[1]]);
+ return app.LOUtil._doRectanglesIntersect(app.file.viewedRectangle.pToArray(), [coords.x, coords.y + partHeightPixels * coords.part, app.tile.size.pixels[0], app.tile.size.pixels[1]]);
}
},
@@ -391,7 +391,7 @@ L.TileSectionManager = L.Class.extend({
_updateWithRAF: function () {
// update-loop with requestAnimationFrame
- this._canvasRAF = L.Util.requestAnimFrame(this._updateWithRAF, this, false /* immediate */);
+ this._canvasRAF = app.util.requestAnimFrame(this._updateWithRAF, this, false /* immediate */);
app.sectionContainer.requestReDraw();
},
@@ -2344,7 +2344,7 @@ L.CanvasTileLayer = L.Layer.extend({
_addView: function(viewInfo) {
if (viewInfo.color === 0 && this._map.getDocType() !== 'text') {
- viewInfo.color = L.LOUtil.getViewIdColor(viewInfo.id);
+ viewInfo.color = app.LOUtil.getViewIdColor(viewInfo.id);
}
this._map.addView(viewInfo);
@@ -2943,7 +2943,7 @@ L.CanvasTileLayer = L.Layer.extend({
var topLeftPixels = this._twipsToCorePixels(topLeftTwips);
var offsetPixels = this._twipsToCorePixels(offset);
- this._cellAutoFillAreaPixels = L.LOUtil.createRectangle(topLeftPixels.x, topLeftPixels.y, offsetPixels.x, offsetPixels.y);
+ this._cellAutoFillAreaPixels = app.LOUtil.createRectangle(topLeftPixels.x, topLeftPixels.y, offsetPixels.x, offsetPixels.y);
}
else {
this._cellAutoFillAreaPixels = null;
@@ -4153,10 +4153,10 @@ L.CanvasTileLayer = L.Layer.extend({
_getTilesSectionRectangle: function () {
var section = app.sectionContainer.getSectionWithName(L.CSections.Tiles.name);
if (section) {
- return L.LOUtil.createRectangle(section.myTopLeft[0] / app.dpiScale, section.myTopLeft[1] / app.dpiScale, section.size[0] / app.dpiScale, section.size[1] / app.dpiScale);
+ return app.LOUtil.createRectangle(section.myTopLeft[0] / app.dpiScale, section.myTopLeft[1] / app.dpiScale, section.size[0] / app.dpiScale, section.size[1] / app.dpiScale);
}
else {
- return L.LOUtil.createRectangle(0, 0, 0, 0);
+ return app.LOUtil.createRectangle(0, 0, 0, 0);
}
},
@@ -4408,7 +4408,7 @@ L.CanvasTileLayer = L.Layer.extend({
viewreset: this._viewReset,
movestart: this._moveStart,
// update tiles on move, but not more often than once per given interval
- move: L.Util.throttle(this._move, this.options.updateInterval, this),
+ move: app.util.throttle(this._move, this.options.updateInterval, this),
moveend: this._moveEnd,
splitposchanged: this._move,
};
@@ -4664,7 +4664,7 @@ L.CanvasTileLayer = L.Layer.extend({
docBoundsRectangle[3] = docBoundsRectangle[3] - docBoundsRectangle[1];
for (i = 0; i < parts.length; i++) {
rectangle = [0, partHeightPixels * parts[i].part, partWidthPixels, partHeightPixels];
- rectangle = L.LOUtil._getIntersectionRectangle(rectangle, docBoundsRectangle);
+ rectangle = app.LOUtil._getIntersectionRectangle(rectangle, docBoundsRectangle);
if (rectangle) {
if (rectangle[2] * rectangle[3] > maxArea) {
maxArea = rectangle[2] * rectangle[3];
@@ -4757,7 +4757,7 @@ L.CanvasTileLayer = L.Layer.extend({
var partWidthPixels = Math.round((this._partWidthTwips) * ratio);
var mode = 0; // mode is different only in Impress MasterPage mode so far
- var intersectionAreaRectangle = L.LOUtil._getIntersectionRectangle(app.file.viewedRectangle.pToArray(), [0, 0, partWidthPixels, partHeightPixels * this._parts]);
+ var intersectionAreaRectangle = app.LOUtil._getIntersectionRectangle(app.file.viewedRectangle.pToArray(), [0, 0, partWidthPixels, partHeightPixels * this._parts]);
var queue = [];
diff --git a/browser/src/layer/vector/Canvas.js b/browser/src/layer/vector/Canvas.js
index bb7d1fe850ecf..8469e42aaff51 100644
--- a/browser/src/layer/vector/Canvas.js
+++ b/browser/src/layer/vector/Canvas.js
@@ -1,4 +1,5 @@
/* -*- js-indent-level: 8 -*- */
+/* global app */
/*
* L.Canvas handles Canvas vector layers rendering and mouse events handling. All Canvas-specific code goes here.
*/
@@ -47,10 +48,10 @@ L.Canvas = L.Renderer.extend({
},
_initPath: function (layer) {
- this._layers[L.stamp(layer)] = layer;
+ this._layers[app.util.stamp(layer)] = layer;
},
- _addPath: L.Util.falseFn,
+ _addPath: app.util.falseFn,
_removePath: function (layer) {
layer._removed = true;
@@ -76,7 +77,7 @@ L.Canvas = L.Renderer.extend({
this._redrawBounds = this._redrawBounds || new L.Bounds();
this._redrawBounds.extend(layer._pxBounds.min).extend(layer._pxBounds.max);
- this._redrawRequest = this._redrawRequest || L.Util.requestAnimFrame(this._redraw, this);
+ this._redrawRequest = this._redrawRequest || app.util.requestAnimFrame(this._redraw, this);
},
_redraw: function () {
@@ -231,8 +232,8 @@ L.Canvas = L.Renderer.extend({
// TODO _bringToFront & _bringToBack, pretty tricky
- _bringToFront: L.Util.falseFn,
- _bringToBack: L.Util.falseFn
+ _bringToFront: app.util.falseFn,
+ _bringToBack: app.util.falseFn
});
L.Browser.canvas = (function () {
diff --git a/browser/src/layer/vector/Path.Drag.js b/browser/src/layer/vector/Path.Drag.js
index e51fe8c5dce8a..1e46f2e77e7d2 100644
--- a/browser/src/layer/vector/Path.Drag.js
+++ b/browser/src/layer/vector/Path.Drag.js
@@ -1,4 +1,5 @@
/* -*- js-indent-level: 8 -*- */
+/* global app */
var END = {
mousedown: 'mouseup',
@@ -253,8 +254,8 @@ L.Handler.PathDrag = L.Handler.extend(/** @lends L.Path.Drag.prototype */ {
// hack for skipping the click in canvas-rendered layers
var contains = this._path._containsPoint;
- this._path._containsPoint = L.Util.falseFn;
- L.Util.requestAnimFrame(function() {
+ this._path._containsPoint = app.util.falseFn;
+ app.util.requestAnimFrame(function() {
L.DomEvent._skipped({ type: 'click' });
this._path._containsPoint = contains;
}, this);
@@ -316,7 +317,7 @@ L.Handler.PathDrag = L.Handler.extend(/** @lends L.Path.Drag.prototype */ {
var rings = path._rings || path._parts;
var latlngs = path._latlngs;
dest = dest || latlngs;
- if (!L.Util.isArray(latlngs[0])) { // polyline
+ if (!app.util.isArray(latlngs[0])) { // polyline
latlngs = [latlngs];
dest = [dest];
}
@@ -346,14 +347,14 @@ L.Handler.PathDrag = L.Handler.extend(/** @lends L.Path.Drag.prototype */ {
_replaceCoordGetters: function() {
if (this._path.getLatLng) { // Circle, CircleMarker
this._path.getLatLng_ = this._path.getLatLng;
- this._path.getLatLng = L.Util.bind(function() {
+ this._path.getLatLng = function() {
return this.dragging._transformPoints(this.dragging._matrix, {});
- }, this._path);
+ }.bind(this._path);
} else if (this._path.getLatLngs) {
this._path.getLatLngs_ = this._path.getLatLngs;
- this._path.getLatLngs = L.Util.bind(function() {
+ this._path.getLatLngs = function() {
return this.dragging._transformPoints(this.dragging._matrix, []);
- }, this._path);
+ }.bind(this._path);
}
},
diff --git a/browser/src/layer/vector/Path.Transform.Util.js b/browser/src/layer/vector/Path.Transform.Util.js
index 0759d59201f99..5aedbe08d4549 100644
--- a/browser/src/layer/vector/Path.Transform.Util.js
+++ b/browser/src/layer/vector/Path.Transform.Util.js
@@ -1,4 +1,5 @@
/* -*- js-indent-level: 8 -*- */
+/* global app */
/**
* @namespace
@@ -49,7 +50,7 @@ L.PathTransform.merge = function() {
val = obj[key];
if (isObject(val) && isObject(target[key])) {
- target[key] = L.Util.merge(target[key], val);
+ target[key] = app.util.merge(target[key], val);
} else {
target[key] = val;
}
diff --git a/browser/src/layer/vector/Path.js b/browser/src/layer/vector/Path.js
index 806d103944d48..e47c6debb7e54 100644
--- a/browser/src/layer/vector/Path.js
+++ b/browser/src/layer/vector/Path.js
@@ -1,4 +1,5 @@
/* -*- js-indent-level: 8 -*- */
+/* global app */
/*
* L.Path is the base class for all Leaflet vector layers like polygons and circles.
*/
@@ -178,7 +179,7 @@ L.Path.PathNodeData = L.Class.extend({
});
L.Path.PathNodeData.key = function (layer) {
- return L.stamp(layer);
+ return app.util.stamp(layer);
};
L.Path.PathNodeCollection = L.Class.extend({
diff --git a/browser/src/layer/vector/Polyline.js b/browser/src/layer/vector/Polyline.js
index ac721e02095e4..8f4dc24686876 100644
--- a/browser/src/layer/vector/Polyline.js
+++ b/browser/src/layer/vector/Polyline.js
@@ -1,4 +1,5 @@
/* -*- js-indent-level: 8 -*- */
+/* global app */
/*
* L.Polyline implements polyline vector layer (a set of points connected with lines)
*/
@@ -82,7 +83,7 @@ L.Polyline = L.Path.extend({
_flat: function (latlngs) {
// true if it's a flat array of latlngs; false if nested
- return !L.Util.isArray(latlngs[0]) || typeof latlngs[0][0] !== 'object';
+ return !app.util.isArray(latlngs[0]) || typeof latlngs[0][0] !== 'object';
},
_project: function () {
diff --git a/browser/src/layer/vector/Renderer.js b/browser/src/layer/vector/Renderer.js
index e1d376949050a..e5f50f2d03271 100644
--- a/browser/src/layer/vector/Renderer.js
+++ b/browser/src/layer/vector/Renderer.js
@@ -1,4 +1,5 @@
/* -*- js-indent-level: 8 -*- */
+/* global app */
/*
* L.Renderer is a base class for renderer implementations (SVG, Canvas);
* handles renderer container, bounds and zoom animation.
@@ -14,7 +15,7 @@ L.Renderer = L.Layer.extend({
initialize: function (options) {
L.setOptions(this, options);
- L.stamp(this);
+ app.util.stamp(this);
},
setParentRenderer: function (parent) {
diff --git a/browser/src/map/Clipboard.js b/browser/src/map/Clipboard.js
index b918d86c8131e..7502d9ca5d13e 100644
--- a/browser/src/map/Clipboard.js
+++ b/browser/src/map/Clipboard.js
@@ -1277,7 +1277,7 @@ L.Clipboard = L.Class.extend({
innerDiv.appendChild(p);
}
else {
- const ctrlText = L.Util.replaceCtrlAltInMac('Ctrl');
+ const ctrlText = app.util.replaceCtrlAltInMac('Ctrl');
const p = document.createElement('p');
p.textContent = 'Your browser has very limited access to the clipboard, so use these keyboard shortcuts:';
innerDiv.appendChild(p);
@@ -1358,7 +1358,7 @@ L.Clipboard = L.Class.extend({
var innerDiv = L.DomUtil.create('div', '', null);
box.insertBefore(innerDiv, box.firstChild);
- const ctrlText = L.Util.replaceCtrlAltInMac('Ctrl');
+ const ctrlText = app.util.replaceCtrlAltInMac('Ctrl');
let p = document.createElement('p');
p.textContent = _('Your browser has very limited access to the clipboard');
diff --git a/browser/src/map/Map.js b/browser/src/map/Map.js
index a3c88b700cbab..6e33e23dae2cd 100644
--- a/browser/src/map/Map.js
+++ b/browser/src/map/Map.js
@@ -45,7 +45,7 @@ L.Map = L.Evented.extend({
tileHeightTwips: window.tileSize * 15,
urlPrefix: 'cool',
wopiSrc: '',
- cursorURL: L.LOUtil.getURL('cursors'),
+ cursorURL: app.LOUtil.getURL('cursors'),
// cursorURL
// The path (local to the server) where custom cursor files are stored.
},
@@ -260,7 +260,7 @@ L.Map = L.Evented.extend({
}, this);
this.on('commandvalues', function(e) {
- if (e.commandName === '.uno:LanguageStatus' && L.Util.isArray(e.commandValues)) {
+ if (e.commandName === '.uno:LanguageStatus' && app.util.isArray(e.commandValues)) {
app.languages = [];
e.commandValues.forEach(function(language) {
var split = language.split(';');
@@ -396,7 +396,7 @@ L.Map = L.Evented.extend({
if (viewInfo.userextrainfo !== undefined && viewInfo.userextrainfo.avatar !== undefined) {
this._viewInfoByUserName[viewInfo.username] = viewInfo;
}
- this.fire('postMessage', {msgId: 'View_Added', args: {Deprecated: true, ViewId: viewInfo.id, UserId: viewInfo.userid, UserName: viewInfo.username, UserExtraInfo: viewInfo.userextrainfo, Color: L.LOUtil.rgbToHex(viewInfo.color), ReadOnly: viewInfo.readonly}});
+ this.fire('postMessage', {msgId: 'View_Added', args: {Deprecated: true, ViewId: viewInfo.id, UserId: viewInfo.userid, UserName: viewInfo.username, UserExtraInfo: viewInfo.userextrainfo, Color: app.LOUtil.rgbToHex(viewInfo.color), ReadOnly: viewInfo.readonly}});
// Fire last, otherwise not all events are handled correctly.
this.fire('addview', {viewId: viewInfo.id, username: viewInfo.username, extraInfo: viewInfo.userextrainfo, readonly: this.isViewReadOnly(viewInfo.id)});
@@ -841,7 +841,7 @@ L.Map = L.Evented.extend({
},
stop: function () {
- L.Util.cancelAnimFrame(this._flyToFrame);
+ app.util.cancelAnimFrame(this._flyToFrame);
if (this._panAnim) {
this._panAnim.stop();
}
@@ -1050,7 +1050,7 @@ L.Map = L.Evented.extend({
project: function (latlng, zoom) { // (LatLng[, Number]) -> Point
zoom = zoom === undefined ? this.getZoom() : zoom;
var projectedPoint = this.options.crs.latLngToPoint(L.latLng(latlng), zoom);
- return new L.Point(L.round(projectedPoint.x, 1e-6), L.round(projectedPoint.y, 1e-6));
+ return new L.Point(app.util.round(projectedPoint.x, 1e-6), app.util.round(projectedPoint.y, 1e-6));
},
unproject: function (point, zoom) { // (Point[, Number]) -> LatLng
@@ -1383,8 +1383,8 @@ L.Map = L.Evented.extend({
},
_onResize: function () {
- L.Util.cancelAnimFrame(this._resizeRequest);
- this._resizeRequest = L.Util.requestAnimFrame(
+ app.util.cancelAnimFrame(this._resizeRequest);
+ this._resizeRequest = app.util.requestAnimFrame(
function () { this.invalidateSize({debounceMoveend: true}); }, this, false, this._container);
if (this.sidebar)
@@ -1532,7 +1532,7 @@ L.Map = L.Evented.extend({
if (!this._docLayer || !this._loaded || !this._enabled || L.DomEvent._skipped(e)) { return; }
// find the layer the event is propagating from
- var target = this._targets[L.stamp(e.target || e.srcElement)],
+ var target = this._targets[app.util.stamp(e.target || e.srcElement)],
//type = e.type === 'keypress' && e.keyCode === 13 ? 'click' : e.type;
type = e.type;
diff --git a/browser/src/map/handler/Map.TouchGesture.js b/browser/src/map/handler/Map.TouchGesture.js
index e1e7deadc66b3..88516401fe8ee 100644
--- a/browser/src/map/handler/Map.TouchGesture.js
+++ b/browser/src/map/handler/Map.TouchGesture.js
@@ -1,4 +1,5 @@
/* -*- js-indent-level: 8; fill-column: 100 -*- */
+/* global app */
/*
* L.Map.CalcTap is used to enable mobile taps.
*/
@@ -438,7 +439,7 @@ L.Map.TouchGesture = L.Handler.extend({
if (window.IgnorePanning)
return;
- L.Util.cancelAnimFrame(this.autoscrollAnimReq);
+ app.util.cancelAnimFrame(this.autoscrollAnimReq);
var point = e.pointers[0],
containerPoint = this._map.mouseEventToContainerPoint(point),
layerPoint = this._map.containerPointToLayerPoint(containerPoint),
@@ -644,7 +645,7 @@ L.Map.TouchGesture = L.Handler.extend({
this._map.dragging._draggable._onDown(evt);
this._timeStamp = Date.now();
this._inSwipeAction = true;
- this.autoscrollAnimReq = L.Util.requestAnimFrame(this._autoscroll, this, true);
+ this.autoscrollAnimReq = app.util.requestAnimFrame(this._autoscroll, this, true);
},
_cancelAutoscrollRAF: function () {
@@ -652,7 +653,7 @@ L.Map.TouchGesture = L.Handler.extend({
this._inSwipeAction = false;
if (app.file.fileBasedView)
this._map._docLayer._checkSelectedPart();
- L.Util.cancelAnimFrame(this.autoscrollAnimReq);
+ app.util.cancelAnimFrame(this.autoscrollAnimReq);
return;
},
@@ -704,7 +705,7 @@ L.Map.TouchGesture = L.Handler.extend({
this._map._docLayer._preFetchTiles(true /* forceBorderCalc */);
if (!horizontalEnd || !verticalEnd) {
- this.autoscrollAnimReq = L.Util.requestAnimFrame(this._autoscroll, this, true);
+ this.autoscrollAnimReq = app.util.requestAnimFrame(this._autoscroll, this, true);
} else {
this._inSwipeAction = false;
if (app.file.fileBasedView)
diff --git a/browser/src/map/handler/Map.WOPI.js b/browser/src/map/handler/Map.WOPI.js
index a6289069dfad4..f9418ab3b7ec1 100644
--- a/browser/src/map/handler/Map.WOPI.js
+++ b/browser/src/map/handler/Map.WOPI.js
@@ -545,7 +545,7 @@ L.Map.WOPI = L.Handler.extend({
this._map.remove();
}
else if (msg.MessageId === 'Action_Fullscreen') {
- L.toggleFullScreen();
+ app.util.toggleFullScreen();
}
else if (msg.MessageId === 'Action_FullscreenPresentation' && this._map.getDocType() === 'presentation') {
if (msg.Values) {
diff --git a/browser/src/map/handler/Map.Welcome.js b/browser/src/map/handler/Map.Welcome.js
index 706fe1bb016cd..84dfed14b7e9f 100644
--- a/browser/src/map/handler/Map.Welcome.js
+++ b/browser/src/map/handler/Map.Welcome.js
@@ -11,7 +11,7 @@ L.Map.mergeOptions({
L.Map.Welcome = L.Handler.extend({
_getLocalWelcomeUrl: function() {
- var welcomeLocation = L.LOUtil.getURL('/welcome/welcome.html');
+ var welcomeLocation = app.LOUtil.getURL('/welcome/welcome.html');
if (window.socketProxy)
welcomeLocation = window.makeWsUrl(welcomeLocation);
return welcomeLocation;