Compare commits

...

4 Commits

Author SHA1 Message Date
Julius Härtl cc506990e0
Add caching for theming inline js
Signed-off-by: Julius Härtl <jus@bitgrid.net>
2019-01-15 21:39:45 +01:00
Julius Härtl fe59d751b3
Always inline js files
Signed-off-by: Julius Härtl <jus@bitgrid.net>
2019-01-15 21:37:07 +01:00
Julius Härtl 3ffb03e8f5
Wait until dom is loaded for adding the theming global
Signed-off-by: Julius Härtl <jus@bitgrid.net>
2019-01-15 21:34:57 +01:00
Roeland Jago Douma 14a3bf225e
First PoC
Signed-off-by: Roeland Jago Douma <roeland@famdouma.nl>
2019-01-15 21:34:56 +01:00
9 changed files with 234 additions and 14 deletions

View File

@ -42,16 +42,4 @@ $linkToCSS = \OC::$server->getURLGenerator()->linkToRoute(
] ]
); );
$linkToJs = \OC::$server->getURLGenerator()->linkToRoute( $app->getContainer()->registerInlineJS(\OCA\Theming\InlineJS::class);
'theming.Theming.getJavascript',
[
'v' => \OC::$server->getConfig()->getAppValue('theming', 'cachebuster', '0'),
]
);
\OCP\Util::addHeader(
'script',
[
'src' => $linkToJs,
'nonce' => \OC::$server->getContentSecurityPolicyNonceManager()->getNonce()
], ''
);

View File

@ -0,0 +1,69 @@
<?php
declare(strict_types=1);
/**
* @copyright Copyright (c) 2019, Roeland Jago Douma <roeland@famdouma.nl>
*
* @author Roeland Jago Douma <roeland@famdouma.nl>
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
namespace OCA\Theming;
use OCP\AppFramework\Http\Inline\IInline;
use OCP\ICache;
use OCP\IConfig;
class InlineJS implements IInline {
/** @var ThemingDefaults */
private $themingDefaults;
/** @var IConfig */
private $config;
/** @var Util */
private $util;
/** @var ICache */
private $cache;
public function __construct(IConfig $config, Util $util, ThemingDefaults $themingDefaults, ICache $cache) {
$this->themingDefaults = $themingDefaults;
$this->config = $config;
$this->util = $util;
$this->cache = $cache;
}
function getData(): string {
$cacheBusterValue = $this->config->getAppValue('theming', 'cachebuster', '0');
if ($this->cache->hasKey('theming-inline-' . $cacheBusterValue)) {
return $this->cache->get('theming-inline-' . $cacheBusterValue);
}
$responseJS = 'document.addEventListener(\'DOMContentLoaded\', function() {
window.OCA.Theming = {
name: ' . json_encode($this->themingDefaults->getName()) . ',
url: ' . json_encode($this->themingDefaults->getBaseUrl()) . ',
slogan: ' . json_encode($this->themingDefaults->getSlogan()) . ',
color: ' . json_encode($this->themingDefaults->getColorPrimary()) . ',
imprintUrl: ' . json_encode($this->themingDefaults->getImprintUrl()) . ',
privacyUrl: ' . json_encode($this->themingDefaults->getPrivacyUrl()) . ',
inverted: ' . json_encode($this->util->invertTextColor($this->themingDefaults->getColorPrimary())) . ',
cacheBuster: ' . json_encode($cacheBusterValue) . '
};
});';
$this->cache->clear('theming-inline-');
$this->cache->set('theming-inline-' . $cacheBusterValue, $responseJS);
return $responseJS;
}
}

View File

@ -2341,7 +2341,7 @@ OC.set=function(name, value) {
* Namespace for apps * Namespace for apps
* @namespace OCA * @namespace OCA
*/ */
window.OCA = {}; window.OCA = window.OCA || {};
/** /**
* select a range in an input field * select a range in an input field

View File

@ -361,6 +361,18 @@ class DIContainer extends SimpleContainer implements IAppContainer {
}); });
} }
public function registerInlineJS(string $serviceName) {
$this->query(\OC\InlineManager::class)->registerJS($this->getAppName(), function() use ($serviceName) {
return $this->query($serviceName);
});
}
public function registerInlineCSS(string $serviceName) {
$this->query(\OC\InlineManager::class)->registerCSS($this->getAppName(), function() use ($serviceName) {
return $this->query($serviceName);
});
}
/** /**
* @param string $name * @param string $name
* @return mixed * @return mixed

View File

@ -0,0 +1,91 @@
<?php
declare(strict_types=1);
/**
* @copyright Copyright (c) 2019, Roeland Jago Douma <roeland@famdouma.nl>
*
* @author Roeland Jago Douma <roeland@famdouma.nl>
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
namespace OC;
use OCP\AppFramework\Http\Inline\IInline;
use OCP\AppFramework\QueryException;
use OCP\ILogger;
class InlineManager {
/** @var ILogger */
private $logger;
/** @var array */
private $js;
/** @var array */
private $css;
public function __construct(ILogger $logger) {
$this->logger = $logger;
}
public function registerJS(string $appName, \Closure $callable) {
$this->js[$appName] = $callable;
}
public function getInlineJS(): array {
$result = [];
foreach ($this->js as $js) {
try {
$c = $js();
} catch (QueryException $e) {
$this->logger->logException($e, [
'message' => 'InlineManager',
'level' => ILogger::ERROR,
'app' => 'core',
]);
continue;
}
if ($c instanceof IInline) {
$result[] = $c->getData();
} else {
$this->logger->error(get_class($c) . ' is not and instance of IInline', [
'app' => 'core',
]);
}
}
return $result;
}
public function getInlineJSApps(): array {
return array_keys($this->js);
}
public function registerCSS(string $appName, \Closure $callable) {
$this->css[$appName] = $callable;
}
public function getInlineCSS(): array {
}
public function getInlineCSSApps(): array {
return array_keys($this->css);
}
}

View File

@ -153,7 +153,10 @@ class TemplateLayout extends \OC_Template {
// Add the js files // Add the js files
$jsFiles = self::findJavascriptFiles(\OC_Util::$scripts); $jsFiles = self::findJavascriptFiles(\OC_Util::$scripts);
$this->assign('jsfiles', array()); $this->assign('jsfiles', array());
$this->assign('jsfiles_inline', []);
if ($this->config->getSystemValue('installed', false) && $renderAs != 'error') { if ($this->config->getSystemValue('installed', false) && $renderAs != 'error') {
/** @var InlineManager $inlineManager */
$inlineManager = \OC::$server->query(InlineManager::class);
if (\OC::$server->getContentSecurityPolicyNonceManager()->browserSupportsCspV3()) { if (\OC::$server->getContentSecurityPolicyNonceManager()->browserSupportsCspV3()) {
$jsConfigHelper = new JSConfigHelper( $jsConfigHelper = new JSConfigHelper(
\OC::$server->getL10N('lib', $localeLang ?: $lang), \OC::$server->getL10N('lib', $localeLang ?: $lang),
@ -171,6 +174,10 @@ class TemplateLayout extends \OC_Template {
} else { } else {
$this->append('jsfiles', \OC::$server->getURLGenerator()->linkToRoute('core.OCJS.getConfig', ['v' => self::$versionHash])); $this->append('jsfiles', \OC::$server->getURLGenerator()->linkToRoute('core.OCJS.getConfig', ['v' => self::$versionHash]));
} }
$inlineJs = $inlineManager->getInlineJS();
foreach ($inlineJs as $js) {
$this->append('jsfiles_inline', $js);
}
} }
foreach($jsFiles as $info) { foreach($jsFiles as $info) {
$web = $info[1]; $web = $info[1];

View File

@ -102,6 +102,11 @@ function emit_script_loading_tags($obj) {
if (!empty($obj['inline_ocjs'])) { if (!empty($obj['inline_ocjs'])) {
emit_script_tag('', $obj['inline_ocjs']); emit_script_tag('', $obj['inline_ocjs']);
} }
if (!empty($obj['jsfiles_inline'])) {
foreach ($obj['jsfiles_inline'] as $item) {
emit_script_tag('', $item);
}
}
} }
/** /**

View File

@ -0,0 +1,36 @@
<?php
declare(strict_types=1);
/**
* @copyright Copyright (c) 2019, Roeland Jago Douma <roeland@famdouma.nl>
*
* @author Roeland Jago Douma <roeland@famdouma.nl>
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
namespace OCP\AppFramework\Http\Inline;
/**
* @since 16.0.0
*/
interface IInline {
/**
* @since 16.0.0
*/
function getData(): string;
}

View File

@ -64,4 +64,16 @@ interface IAppContainer extends IContainer {
* @since 8.2.0 * @since 8.2.0
*/ */
public function registerCapability($serviceName); public function registerCapability($serviceName);
/**
* Register inline JS
* @since 16.0.0
*/
public function registerInlineJS(string $serviceName);
/**
* Register inline CSS
* @scine 16.0.0
*/
public function registerInlineCSS(string $serviceName);
} }