first
This commit is contained in:
@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
|
||||
namespace Nextend\Framework\Font;
|
||||
|
||||
|
||||
use Nextend\Framework\Form\ContainerInterface;
|
||||
|
||||
abstract class AbstractFontSource {
|
||||
|
||||
protected $name;
|
||||
|
||||
public abstract function getLabel();
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getName() {
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
public function onFontManagerLoad($force = false) {
|
||||
|
||||
}
|
||||
|
||||
public function onFontManagerLoadBackend() {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ContainerInterface $container
|
||||
*/
|
||||
abstract public function renderFields($container);
|
||||
}
|
@ -0,0 +1,57 @@
|
||||
<?php
|
||||
|
||||
|
||||
namespace Nextend\Framework\Font\Block\FontManager;
|
||||
|
||||
|
||||
use Nextend\Framework\Asset\Js\Js;
|
||||
use Nextend\Framework\Font\FontRenderer;
|
||||
use Nextend\Framework\Font\FontSettings;
|
||||
use Nextend\Framework\Font\ModelFont;
|
||||
use Nextend\Framework\Visual\AbstractBlockVisual;
|
||||
use Nextend\SmartSlider3\Application\Admin\Layout\Block\Forms\Button\BlockButtonApply;
|
||||
use Nextend\SmartSlider3\Application\Admin\Layout\Block\Forms\Button\BlockButtonCancel;
|
||||
|
||||
class BlockFontManager extends AbstractBlockVisual {
|
||||
|
||||
/** @var ModelFont */
|
||||
protected $model;
|
||||
|
||||
/**
|
||||
* @return ModelFont
|
||||
*/
|
||||
public function getModel() {
|
||||
return $this->model;
|
||||
}
|
||||
|
||||
public function display() {
|
||||
|
||||
$this->model = new ModelFont($this);
|
||||
|
||||
$this->renderTemplatePart('Index');
|
||||
}
|
||||
|
||||
public function displayTopBar() {
|
||||
|
||||
$buttonCancel = new BlockButtonCancel($this);
|
||||
$buttonCancel->addClass('n2_fullscreen_editor__cancel');
|
||||
$buttonCancel->display();
|
||||
|
||||
$buttonApply = new BlockButtonApply($this);
|
||||
$buttonApply->addClass('n2_fullscreen_editor__save');
|
||||
$buttonApply->display();
|
||||
}
|
||||
|
||||
public function displayContent() {
|
||||
$model = $this->getModel();
|
||||
|
||||
Js::addFirstCode("
|
||||
_N2.CSSRendererFont.defaultFamily = " . json_encode(FontSettings::getDefaultFamily()) . ";
|
||||
_N2.CSSRendererFont.rendererModes = " . json_encode(FontRenderer::$mode) . ";
|
||||
_N2.CSSRendererFont.pre = " . json_encode(FontRenderer::$pre) . ";
|
||||
new _N2.NextendFontManager();
|
||||
");
|
||||
|
||||
$model->renderForm();
|
||||
}
|
||||
}
|
@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
namespace Nextend\Framework\Font\Block\FontManager;
|
||||
|
||||
/**
|
||||
* @var BlockFontManager $this
|
||||
*/
|
||||
?>
|
||||
<div id="n2-lightbox-font" class="n2_fullscreen_editor">
|
||||
<div class="n2_fullscreen_editor__overlay"></div>
|
||||
<div class="n2_fullscreen_editor__window">
|
||||
<div class="n2_fullscreen_editor__nav_bar">
|
||||
<div class="n2_fullscreen_editor__nav_bar_label">
|
||||
<?php n2_e('Font manager'); ?>
|
||||
</div>
|
||||
<div class="n2_fullscreen_editor__nav_bar_actions">
|
||||
<?php $this->displayTopBar(); ?>
|
||||
</div>
|
||||
</div>
|
||||
<div class="n2_fullscreen_editor__content">
|
||||
<div class="n2_fullscreen_editor__content_content n2_container_scrollable">
|
||||
<?php $this->displayContent(); ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
@ -0,0 +1,15 @@
|
||||
<?php
|
||||
|
||||
namespace Nextend\Framework\Font;
|
||||
|
||||
use Nextend\Framework\Controller\Admin\AdminVisualManagerAjaxController;
|
||||
|
||||
class ControllerAjaxFont extends AdminVisualManagerAjaxController {
|
||||
|
||||
protected $type = 'font';
|
||||
|
||||
public function getModel() {
|
||||
|
||||
return new ModelFont($this);
|
||||
}
|
||||
}
|
@ -0,0 +1,17 @@
|
||||
<?php
|
||||
|
||||
namespace Nextend\Framework\Font;
|
||||
|
||||
use Nextend\Framework\Font\Block\FontManager\BlockFontManager;
|
||||
use Nextend\Framework\Pattern\VisualManagerTrait;
|
||||
|
||||
class FontManager {
|
||||
|
||||
use VisualManagerTrait;
|
||||
|
||||
public function display() {
|
||||
|
||||
$fontManagerBlock = new BlockFontManager($this->MVCHelper);
|
||||
$fontManagerBlock->display();
|
||||
}
|
||||
}
|
@ -0,0 +1,62 @@
|
||||
<?php
|
||||
|
||||
|
||||
namespace Nextend\Framework\Font;
|
||||
|
||||
|
||||
use Nextend\Framework\Misc\Base64;
|
||||
use Nextend\Framework\Model\Section;
|
||||
|
||||
class FontParser {
|
||||
|
||||
/**
|
||||
* @param $data
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function parse($data) {
|
||||
if (empty($data)) {
|
||||
return '';
|
||||
} else if (is_numeric($data)) {
|
||||
/**
|
||||
* Linked font
|
||||
*/
|
||||
|
||||
$font = Section::getById($data, 'font');
|
||||
|
||||
if (!$font) {
|
||||
/**
|
||||
* Linked font not exists anymore
|
||||
*/
|
||||
return '';
|
||||
}
|
||||
|
||||
|
||||
if (is_string($font['value'])) {
|
||||
/**
|
||||
* Old format when value stored as Base64
|
||||
*/
|
||||
$decoded = $font['value'];
|
||||
if ($decoded[0] != '{') {
|
||||
$decoded = Base64::decode($decoded);
|
||||
}
|
||||
|
||||
return $decoded;
|
||||
}
|
||||
|
||||
/**
|
||||
* Value stored as array
|
||||
*/
|
||||
$value = json_encode($font['value']);
|
||||
if ($value == false) {
|
||||
return '';
|
||||
}
|
||||
|
||||
return $value;
|
||||
} else if ($data[0] != '{') {
|
||||
return Base64::decode($data);
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
}
|
@ -0,0 +1,260 @@
|
||||
<?php
|
||||
|
||||
namespace Nextend\Framework\Font;
|
||||
|
||||
use Nextend\Framework\Settings;
|
||||
|
||||
class FontRenderer {
|
||||
|
||||
public static $defaultFont = 'Montserrat';
|
||||
|
||||
public static $pre = '';
|
||||
|
||||
/**
|
||||
* @var FontStyle
|
||||
*/
|
||||
public static $style;
|
||||
|
||||
public static $mode;
|
||||
|
||||
public static function setDefaultFont($fontFamily) {
|
||||
self::$defaultFont = $fontFamily;
|
||||
}
|
||||
|
||||
public static function render($font, $mode, $pre = '', $fontSize = false) {
|
||||
self::$pre = $pre;
|
||||
|
||||
if (!empty($font)) {
|
||||
$value = json_decode($font, true);
|
||||
if ($value) {
|
||||
$selector = 'n2-font-' . md5($font) . '-' . $mode;
|
||||
|
||||
return array(
|
||||
$selector . ' ',
|
||||
self::renderFont($mode, $pre, $selector, $value['data'], $fontSize)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private static function renderFont($mode, $pre, $selector, $tabs, $fontSize) {
|
||||
$search = array(
|
||||
'@pre',
|
||||
'@selector'
|
||||
);
|
||||
$replace = array(
|
||||
$pre,
|
||||
'.' . $selector
|
||||
);
|
||||
$tabs[0] = array_merge(array(
|
||||
'afont' => self::$defaultFont,
|
||||
'color' => '000000ff',
|
||||
'size' => '14||px',
|
||||
'tshadow' => '0|*|0|*|0|*|000000ff',
|
||||
'lineheight' => '1.5',
|
||||
'bold' => 0,
|
||||
'italic' => 0,
|
||||
'underline' => 0,
|
||||
'align' => 'left',
|
||||
'letterspacing' => "normal",
|
||||
'wordspacing' => "normal",
|
||||
'texttransform' => "none",
|
||||
'extra' => ''
|
||||
), $tabs[0]);
|
||||
|
||||
if (self::$mode[$mode]['renderOptions']['combined']) {
|
||||
for ($i = 1; $i < count($tabs); $i++) {
|
||||
$tabs[$i] = array_merge($tabs[$i - 1], $tabs[$i]);
|
||||
if ($tabs[$i]['size'] == $tabs[0]['size']) {
|
||||
$tabs[$i]['size'] = '100||%';
|
||||
} else {
|
||||
$size1 = explode('||', $tabs[0]['size']);
|
||||
$size2 = explode('||', $tabs[$i]['size']);
|
||||
if (isset($size1[1]) && isset($size2[1]) && $size1[1] == 'px' && $size2[1] == 'px') {
|
||||
$tabs[$i]['size'] = round($size2[0] / $size1[0] * 100) . '||%';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
foreach ($tabs as $k => $tab) {
|
||||
$search[] = '@tab' . $k;
|
||||
FontStyle::$fontSize = $fontSize;
|
||||
$replace[] = self::$style->style($tab);
|
||||
}
|
||||
|
||||
$template = '';
|
||||
foreach (self::$mode[$mode]['selectors'] as $s => $style) {
|
||||
$key = array_search($style, $search);
|
||||
if (is_numeric($key) && !empty($replace[$key])) {
|
||||
$template .= $s . "{" . $style . "}";
|
||||
}
|
||||
}
|
||||
|
||||
return str_replace($search, $replace, $template);
|
||||
}
|
||||
}
|
||||
|
||||
$frontendAccessibility = intval(Settings::get('frontend-accessibility', 1));
|
||||
|
||||
FontRenderer::$mode = array(
|
||||
'0' => array(
|
||||
'id' => '0',
|
||||
'label' => n2_('Text'),
|
||||
'tabs' => array(
|
||||
n2_('Text')
|
||||
),
|
||||
'renderOptions' => array(
|
||||
'combined' => false
|
||||
),
|
||||
'preview' => '<div class="{fontClassName}">Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</div>',
|
||||
'selectors' => array(
|
||||
'@pre@selector' => '@tab0'
|
||||
)
|
||||
),
|
||||
'simple' => array(
|
||||
'id' => 'simple',
|
||||
'label' => n2_('Text'),
|
||||
'tabs' => array(
|
||||
n2_('Text')
|
||||
),
|
||||
'renderOptions' => array(
|
||||
'combined' => false
|
||||
),
|
||||
'preview' => '<div class="{fontClassName}">Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</div>',
|
||||
'selectors' => array(
|
||||
'@pre@selector' => '@tab0'
|
||||
)
|
||||
),
|
||||
'hover' => array(
|
||||
'id' => 'hover',
|
||||
'label' => n2_('Hover'),
|
||||
'tabs' => array(
|
||||
n2_('Text'),
|
||||
n2_('Hover')
|
||||
),
|
||||
'renderOptions' => array(
|
||||
'combined' => false
|
||||
),
|
||||
'preview' => '<div class="{fontClassName}">' . n2_('Heading') . '</div>',
|
||||
'selectors' => $frontendAccessibility ? array(
|
||||
'@pre@selector' => '@tab0',
|
||||
'@pre@selector:HOVER, @pre@selector:ACTIVE, @pre@selector:FOCUS' => '@tab1'
|
||||
) : array(
|
||||
'@pre@selector, @pre@selector:FOCUS' => '@tab0',
|
||||
'@pre@selector:HOVER, @pre@selector:ACTIVE' => '@tab1'
|
||||
)
|
||||
),
|
||||
'link' => array(
|
||||
'id' => 'link',
|
||||
'label' => n2_('Link'),
|
||||
'tabs' => array(
|
||||
n2_('Text'),
|
||||
n2_('Hover')
|
||||
),
|
||||
'renderOptions' => array(
|
||||
'combined' => false
|
||||
),
|
||||
'preview' => '<div class="{fontClassName}"><a href="#" onclick="return false;">' . n2_('Button') . '</a></div>',
|
||||
'selectors' => $frontendAccessibility ? array(
|
||||
'@pre@selector a' => '@tab0',
|
||||
'@pre@selector a:HOVER, @pre@selector a:ACTIVE, @pre@selector a:FOCUS' => '@tab1'
|
||||
) : array(
|
||||
'@pre@selector a, @pre@selector a:FOCUS' => '@tab0',
|
||||
'@pre@selector a:HOVER, @pre@selector a:ACTIVE' => '@tab1'
|
||||
)
|
||||
),
|
||||
'paragraph' => array(
|
||||
'id' => 'paragraph',
|
||||
'label' => n2_('Paragraph'),
|
||||
'tabs' => array(
|
||||
n2_('Text'),
|
||||
n2_('Link'),
|
||||
n2_('Hover')
|
||||
),
|
||||
'renderOptions' => array(
|
||||
'combined' => true
|
||||
),
|
||||
'preview' => '<div class="{fontClassName}">Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do <a href="#">test link</a> incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in <a href="#">test link</a> velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat <a href="#">test link</a>, sunt in culpa qui officia deserunt mollit anim id est laborum.</div>',
|
||||
'selectors' => array(
|
||||
'@pre@selector' => '@tab0',
|
||||
'@pre@selector a, @pre@selector a:FOCUS' => '@tab1',
|
||||
'@pre@selector a:HOVER, @pre@selector a:ACTIVE' => '@tab2'
|
||||
)
|
||||
),
|
||||
'input' => array(
|
||||
'id' => 'input',
|
||||
'label' => 'Input',
|
||||
'tabs' => array(
|
||||
n2_('Text'),
|
||||
n2_('Hover')
|
||||
),
|
||||
'renderOptions' => array(
|
||||
'combined' => false
|
||||
),
|
||||
'preview' => '<div class="{fontClassName}">Excepteur sint occaecat</div>',
|
||||
'selectors' => array(
|
||||
'@pre@selector' => '@tab0',
|
||||
'@pre@selector:HOVER, @pre@selector:FOCUS' => '@tab2'
|
||||
)
|
||||
),
|
||||
'dot' => array(
|
||||
'id' => 'dot',
|
||||
'label' => n2_('Dot'),
|
||||
'tabs' => array(
|
||||
n2_('Text'),
|
||||
n2_('Active')
|
||||
),
|
||||
'renderOptions' => array(
|
||||
'combined' => false
|
||||
),
|
||||
'preview' => '',
|
||||
'selectors' => array(
|
||||
'@pre@selector, @pre@selector:FOCUS' => '@tab0',
|
||||
'@pre@selector.n2-active, @pre@selector:HOVER, @pre@selector:ACTIVE' => '@tab1'
|
||||
)
|
||||
),
|
||||
'list' => array(
|
||||
'id' => 'list',
|
||||
'label' => n2_('List'),
|
||||
'tabs' => array(
|
||||
n2_('Text'),
|
||||
n2_('Link'),
|
||||
n2_('Hover')
|
||||
),
|
||||
'renderOptions' => array(
|
||||
'combined' => false
|
||||
),
|
||||
'preview' => '',
|
||||
'selectors' => array(
|
||||
'@pre@selector li' => '@tab0',
|
||||
'@pre@selector li a, @pre@selector li a:FOCUS' => '@tab1',
|
||||
'@pre@selector li a:HOVER, @pre@selector li a:ACTIVE' => '@tab2'
|
||||
)
|
||||
),
|
||||
'highlight' => array(
|
||||
'id' => 'highlight',
|
||||
'label' => n2_('Highlight'),
|
||||
'tabs' => array(
|
||||
n2_('Text'),
|
||||
n2_('Highlight'),
|
||||
n2_('Hover')
|
||||
),
|
||||
'renderOptions' => array(
|
||||
'combined' => true
|
||||
),
|
||||
'preview' => '<div class="{fontClassName}">' . n2_('Button') . '</div>',
|
||||
'selectors' => $frontendAccessibility ? array(
|
||||
'@pre@selector' => '@tab0',
|
||||
'@pre@selector .n2-highlighted' => '@tab1',
|
||||
'@pre@selector .n2-highlighted:HOVER, @pre@selector .n2-highlighted:ACTIVE, @pre@selector .n2-highlighted:FOCUS' => '@tab2'
|
||||
) : array(
|
||||
'@pre@selector' => '@tab0',
|
||||
'@pre@selector .n2-highlighted, @pre@selector .n2-highlighted:FOCUS' => '@tab1',
|
||||
'@pre@selector .n2-highlighted:HOVER, @pre@selector .n2-highlighted:ACTIVE' => '@tab2'
|
||||
)
|
||||
),
|
||||
);
|
||||
|
||||
FontRenderer::$style = new FontStyle();
|
@ -0,0 +1,138 @@
|
||||
<?php
|
||||
|
||||
|
||||
namespace Nextend\Framework\Font;
|
||||
|
||||
|
||||
use Nextend\Framework\Data\Data;
|
||||
use Nextend\Framework\Model\Section;
|
||||
|
||||
class FontSettings {
|
||||
|
||||
/**
|
||||
* @var Data
|
||||
*/
|
||||
private static $data;
|
||||
|
||||
/**
|
||||
* @var Data
|
||||
*/
|
||||
private static $pluginsData;
|
||||
|
||||
public function __construct() {
|
||||
self::load();
|
||||
FontRenderer::setDefaultFont(self::$data->get('default-family'));
|
||||
}
|
||||
|
||||
public static function load() {
|
||||
|
||||
self::$data = new Data(array(
|
||||
'default-family' => n2_x('Roboto,Arial', 'Default font'),
|
||||
'preset-families' => n2_x(implode("\n", array(
|
||||
"Abel",
|
||||
"Arial",
|
||||
"Arimo",
|
||||
"Average",
|
||||
"Bevan",
|
||||
"Bitter",
|
||||
"'Bree Serif'",
|
||||
"Cabin",
|
||||
"Calligraffitti",
|
||||
"Chewy",
|
||||
"Comfortaa",
|
||||
"'Covered By Your Grace'",
|
||||
"'Crafty Girls'",
|
||||
"'Dancing Script'",
|
||||
"'Noto Sans'",
|
||||
"'Noto Serif'",
|
||||
"'Francois One'",
|
||||
"'Fredoka One'",
|
||||
"'Gloria Hallelujah'",
|
||||
"'Happy Monkey'",
|
||||
"'Josefin Slab'",
|
||||
"Lato",
|
||||
"Lobster",
|
||||
"'Luckiest Guy'",
|
||||
"Montserrat",
|
||||
"'Nova Square'",
|
||||
"Nunito",
|
||||
"'Open Sans'",
|
||||
"Oswald",
|
||||
"Oxygen",
|
||||
"Pacifico",
|
||||
"'Permanent Marker'",
|
||||
"'Playfair Display'",
|
||||
"'PT Sans'",
|
||||
"'Poiret One'",
|
||||
"Raleway",
|
||||
"Roboto",
|
||||
"'Rock Salt'",
|
||||
"Quicksand",
|
||||
"Satisfy",
|
||||
"'Squada One'",
|
||||
"'The Girl Next Door'",
|
||||
"'Titillium Web'",
|
||||
"'Varela Round'",
|
||||
"Vollkorn",
|
||||
"'Walter Turncoat'"
|
||||
)), 'Default font family list'),
|
||||
'plugins' => array()
|
||||
));
|
||||
|
||||
foreach (Section::getAll('system', 'fonts') as $data) {
|
||||
self::$data->set($data['referencekey'], $data['value']);
|
||||
}
|
||||
|
||||
self::$pluginsData = new Data(self::$data->get('plugins'), true);
|
||||
}
|
||||
|
||||
public static function store($data) {
|
||||
if (is_array($data)) {
|
||||
foreach ($data as $key => $value) {
|
||||
if (self::$data->has($key)) {
|
||||
self::$data->set($key, $value);
|
||||
Section::set('system', 'fonts', $key, $value, 1, 1);
|
||||
unset($data[$key]);
|
||||
}
|
||||
}
|
||||
if (count($data)) {
|
||||
self::$pluginsData = new Data($data);
|
||||
Section::set('system', 'fonts', 'plugins', self::$pluginsData->toJSON(), 1, 1);
|
||||
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Data
|
||||
*/
|
||||
public static function getData() {
|
||||
|
||||
return self::$data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Data
|
||||
*/
|
||||
public static function getPluginsData() {
|
||||
|
||||
return self::$pluginsData;
|
||||
}
|
||||
|
||||
public static function getDefaultFamily() {
|
||||
return self::$data->get('default-family');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public static function getPresetFamilies() {
|
||||
return array_filter(explode("\n", self::$data->get('preset-families')));
|
||||
}
|
||||
}
|
||||
|
||||
new FontSettings();
|
@ -0,0 +1,55 @@
|
||||
<?php
|
||||
|
||||
|
||||
namespace Nextend\Framework\Font;
|
||||
|
||||
|
||||
use Nextend\Framework\Filesystem\Filesystem;
|
||||
|
||||
class FontSources {
|
||||
|
||||
/** @var AbstractFontSource[] */
|
||||
private static $fontSources = array();
|
||||
|
||||
public function __construct() {
|
||||
$dir = dirname(__FILE__) . '/Sources/';
|
||||
foreach (Filesystem::folders($dir) as $folder) {
|
||||
$file = $dir . $folder . '/' . $folder . '.php';
|
||||
if (Filesystem::fileexists($file)) {
|
||||
require_once($file);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $class
|
||||
*/
|
||||
public static function registerSource($class) {
|
||||
|
||||
/** @var AbstractFontSource $source */
|
||||
$source = new $class();
|
||||
|
||||
self::$fontSources[$source->getName()] = $source;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return AbstractFontSource[]
|
||||
*/
|
||||
public static function getFontSources() {
|
||||
return self::$fontSources;
|
||||
}
|
||||
|
||||
public static function onFontManagerLoad($force = false) {
|
||||
foreach (self::$fontSources as $source) {
|
||||
$source->onFontManagerLoad($force);
|
||||
}
|
||||
}
|
||||
|
||||
public static function onFontManagerLoadBackend() {
|
||||
foreach (self::$fontSources as $source) {
|
||||
$source->onFontManagerLoadBackend();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
new FontSources();
|
@ -0,0 +1,93 @@
|
||||
<?php
|
||||
|
||||
|
||||
namespace Nextend\Framework\Font;
|
||||
|
||||
use Nextend\Framework\Pattern\SingletonTrait;
|
||||
use Nextend\Framework\Plugin;
|
||||
|
||||
class FontStorage {
|
||||
|
||||
use SingletonTrait;
|
||||
|
||||
private $sets = array();
|
||||
|
||||
private $fonts = array();
|
||||
|
||||
private $fontsBySet = array();
|
||||
|
||||
private $fontsById = array();
|
||||
|
||||
protected function init() {
|
||||
|
||||
Plugin::addAction('systemfontset', array(
|
||||
$this,
|
||||
'fontSet'
|
||||
));
|
||||
Plugin::addAction('systemfont', array(
|
||||
$this,
|
||||
'fonts'
|
||||
));
|
||||
Plugin::addAction('font', array(
|
||||
$this,
|
||||
'font'
|
||||
));
|
||||
}
|
||||
|
||||
private function load() {
|
||||
static $loaded;
|
||||
if (!$loaded) {
|
||||
Plugin::doAction('fontStorage', array(
|
||||
&$this->sets,
|
||||
&$this->fonts
|
||||
));
|
||||
|
||||
for ($i = 0; $i < count($this->fonts); $i++) {
|
||||
if (!isset($this->fontsBySet[$this->fonts[$i]['referencekey']])) {
|
||||
$this->fontsBySet[$this->fonts[$i]['referencekey']] = array();
|
||||
}
|
||||
$this->fontsBySet[$this->fonts[$i]['referencekey']][] = &$this->fonts[$i];
|
||||
$this->fontsById[$this->fonts[$i]['id']] = &$this->fonts[$i];
|
||||
}
|
||||
$loaded = true;
|
||||
}
|
||||
}
|
||||
|
||||
public function fontSet($referenceKey, &$sets) {
|
||||
|
||||
$this->load();
|
||||
|
||||
for ($i = count($this->sets) - 1; $i >= 0; $i--) {
|
||||
$this->sets[$i]['isSystem'] = 1;
|
||||
$this->sets[$i]['editable'] = 0;
|
||||
array_unshift($sets, $this->sets[$i]);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public function fonts($referenceKey, &$fonts) {
|
||||
|
||||
$this->load();
|
||||
|
||||
if (isset($this->fontsBySet[$referenceKey])) {
|
||||
$_fonts = &$this->fontsBySet[$referenceKey];
|
||||
for ($i = count($_fonts) - 1; $i >= 0; $i--) {
|
||||
$_fonts[$i]['isSystem'] = 1;
|
||||
$_fonts[$i]['editable'] = 0;
|
||||
array_unshift($fonts, $_fonts[$i]);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public function font($id, &$font) {
|
||||
|
||||
$this->load();
|
||||
|
||||
if (isset($this->fontsById[$id])) {
|
||||
$this->fontsById[$id]['isSystem'] = 1;
|
||||
$this->fontsById[$id]['editable'] = 0;
|
||||
$font = $this->fontsById[$id];
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,197 @@
|
||||
<?php
|
||||
|
||||
|
||||
namespace Nextend\Framework\Font;
|
||||
|
||||
|
||||
use Nextend\Framework\Parser\Color;
|
||||
use Nextend\Framework\Parser\Common;
|
||||
use Nextend\Framework\Plugin;
|
||||
use Nextend\Framework\Sanitize;
|
||||
|
||||
class FontStyle {
|
||||
|
||||
public static $fontSize = false;
|
||||
|
||||
/**
|
||||
* @param string $tab
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function style($tab) {
|
||||
$style = '';
|
||||
$extra = '';
|
||||
if (isset($tab['extra'])) {
|
||||
$extra = $tab['extra'];
|
||||
unset($tab['extra']);
|
||||
}
|
||||
foreach ($tab as $k => $v) {
|
||||
$style .= $this->parse($k, $v);
|
||||
}
|
||||
$style .= $this->parse('extra', $extra);
|
||||
|
||||
return $style;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $property
|
||||
* @param $value
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function parse($property, $value) {
|
||||
$fn = 'parse' . $property;
|
||||
|
||||
return $this->$fn($value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $v
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function parseColor($v) {
|
||||
$hex = Color::hex82hex($v);
|
||||
if ($hex[1] == 'ff') {
|
||||
return 'color: #' . $hex[0] . ';';
|
||||
}
|
||||
|
||||
$rgba = Color::hex2rgba($v);
|
||||
|
||||
return 'color: RGBA(' . $rgba[0] . ',' . $rgba[1] . ',' . $rgba[2] . ',' . round($rgba[3] / 127, 2) . ');';
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $v
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function parseSize($v) {
|
||||
if (self::$fontSize) {
|
||||
$fontSize = Common::parse($v);
|
||||
if ($fontSize[1] == 'px') {
|
||||
return 'font-size:' . ($fontSize[0] / self::$fontSize * 100) . '%;';
|
||||
}
|
||||
}
|
||||
|
||||
return 'font-size:' . Sanitize::esc_css_value(Common::parse($v, '')) . ';';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $v
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function parseTshadow($v) {
|
||||
$v = Common::parse($v);
|
||||
$rgba = Color::hex2rgba($v[3]);
|
||||
if ($v[0] == 0 && $v[1] == 0 && $v[2] == 0) return 'text-shadow: none;';
|
||||
|
||||
return 'text-shadow: ' . Sanitize::esc_css_value($v[0]) . 'px ' . Sanitize::esc_css_value($v[1]) . 'px ' . Sanitize::esc_css_value($v[2]) . 'px RGBA(' . $rgba[0] . ',' . $rgba[1] . ',' . $rgba[2] . ',' . round($rgba[3] / 127, 2) . ');';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $v
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function parseAfont($v) {
|
||||
return 'font-family: ' . $this->loadFont(Sanitize::esc_css_value($v)) . ';';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $v
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function parseLineheight($v) {
|
||||
if ($v == '') return '';
|
||||
|
||||
return 'line-height: ' . Sanitize::esc_css_value($v) . ';';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $v
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function parseBold($v) {
|
||||
return $this->parseWeight($v);
|
||||
}
|
||||
|
||||
public function parseWeight($v) {
|
||||
if ($v == '1') return 'font-weight: bold;';
|
||||
if ($v > 1) return 'font-weight: ' . intval($v) . ';';
|
||||
|
||||
return 'font-weight: normal;';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $v
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function parseItalic($v) {
|
||||
if ($v == '1') return 'font-style: italic;';
|
||||
|
||||
return 'font-style: normal;';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $v
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function parseUnderline($v) {
|
||||
if ($v == '1') return 'text-decoration: underline;';
|
||||
|
||||
return 'text-decoration: none;';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $v
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function parseAlign($v) {
|
||||
return 'text-align: ' . Sanitize::esc_css_value($v) . ';';
|
||||
}
|
||||
|
||||
public function parseLetterSpacing($v) {
|
||||
return 'letter-spacing: ' . Sanitize::esc_css_value($v) . ';';
|
||||
}
|
||||
|
||||
public function parseWordSpacing($v) {
|
||||
return 'word-spacing: ' . Sanitize::esc_css_value($v) . ';';
|
||||
}
|
||||
|
||||
public function parseTextTransform($v) {
|
||||
return 'text-transform: ' . Sanitize::esc_css_value($v) . ';';
|
||||
}
|
||||
|
||||
public function parseExtra($v) {
|
||||
|
||||
return Sanitize::esc_css_string($v);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $families
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function loadFont($families) {
|
||||
$families = explode(',', $families);
|
||||
for ($i = 0; $i < count($families); $i++) {
|
||||
if ($families[$i] != "inherit") {
|
||||
$families[$i] = $this->getFamily(trim(trim($families[$i]), '\'"'));
|
||||
}
|
||||
}
|
||||
|
||||
return implode(',', $families);
|
||||
}
|
||||
|
||||
private function getFamily($family) {
|
||||
return "'" . Plugin::applyFilters('fontFamily', $family) . "'";
|
||||
}
|
||||
}
|
@ -0,0 +1,108 @@
|
||||
<?php
|
||||
|
||||
namespace Nextend\Framework\Font;
|
||||
|
||||
use Nextend\Framework\Form\Container\ContainerTable;
|
||||
use Nextend\Framework\Form\Element\Button;
|
||||
use Nextend\Framework\Form\Element\Decoration;
|
||||
use Nextend\Framework\Form\Element\MixedField;
|
||||
use Nextend\Framework\Form\Element\Radio\TextAlign;
|
||||
use Nextend\Framework\Form\Element\Select;
|
||||
use Nextend\Framework\Form\Element\Select\FontWeight;
|
||||
use Nextend\Framework\Form\Element\Tab;
|
||||
use Nextend\Framework\Form\Element\Text\Color;
|
||||
use Nextend\Framework\Form\Element\Text\Family;
|
||||
use Nextend\Framework\Form\Element\Text\TextAutoComplete;
|
||||
use Nextend\Framework\Form\Element\Textarea;
|
||||
use Nextend\Framework\Form\Form;
|
||||
use Nextend\Framework\Visual\ModelVisual;
|
||||
|
||||
class ModelFont extends ModelVisual {
|
||||
|
||||
protected $type = 'font';
|
||||
|
||||
public function renderForm() {
|
||||
|
||||
$form = new Form($this, 'n2-font-editor');
|
||||
|
||||
$table = new ContainerTable($form->getContainer(), 'font', n2_('Font settings'));
|
||||
|
||||
$table->setFieldsetPositionEnd();
|
||||
|
||||
new Button($table->getFieldsetLabel(), 'font-clear-tab', false, n2_('Clear tab'));
|
||||
|
||||
new Tab($table->getFieldsetLabel(), 'font-state');
|
||||
|
||||
$row1 = $table->createRow('font-row-1');
|
||||
new Family($row1, 'family', n2_('Family'), 'Arial, Helvetica', array(
|
||||
'style' => 'width:150px;'
|
||||
));
|
||||
new Color($row1, 'color', n2_('Color'), '000000FF', array(
|
||||
'alpha' => true
|
||||
));
|
||||
|
||||
new MixedField\FontSize($row1, 'size', n2_('Size'), '14|*|px');
|
||||
|
||||
new FontWeight($row1, 'weight', n2_('Font weight'), '');
|
||||
new Decoration($row1, 'decoration', n2_('Decoration'));
|
||||
new TextAutoComplete($row1, 'lineheight', n2_('Line height'), '18px', array(
|
||||
'values' => array(
|
||||
'normal',
|
||||
'1',
|
||||
'1.2',
|
||||
'1.5',
|
||||
'1.8',
|
||||
'2'
|
||||
),
|
||||
'style' => 'width:70px;'
|
||||
));
|
||||
new TextAlign($row1, 'textalign', n2_('Text align'), 'inherit');
|
||||
|
||||
$row2 = $table->createRow('font-row-2');
|
||||
|
||||
new TextAutoComplete($row2, 'letterspacing', n2_('Letter spacing'), 'normal', array(
|
||||
'values' => array(
|
||||
'normal',
|
||||
'1px',
|
||||
'2px',
|
||||
'5px',
|
||||
'10px',
|
||||
'15px'
|
||||
),
|
||||
'style' => 'width:50px;'
|
||||
));
|
||||
new TextAutoComplete($row2, 'wordspacing', n2_('Word spacing'), 'normal', array(
|
||||
'values' => array(
|
||||
'normal',
|
||||
'2px',
|
||||
'5px',
|
||||
'10px',
|
||||
'15px'
|
||||
),
|
||||
'style' => 'width:50px;'
|
||||
));
|
||||
new Select($row2, 'texttransform', n2_('Transform'), 'none', array(
|
||||
'options' => array(
|
||||
'none' => n2_('None'),
|
||||
'capitalize' => n2_('Capitalize'),
|
||||
'uppercase' => n2_('Uppercase'),
|
||||
'lowercase' => n2_('Lowercase')
|
||||
)
|
||||
));
|
||||
|
||||
new MixedField\TextShadow($row2, 'tshadow', n2_('Text shadow'), '0|*|0|*|1|*|000000FF');
|
||||
|
||||
new Textarea($row2, 'extracss', 'CSS', '', array(
|
||||
'width' => 200,
|
||||
'height' => 26
|
||||
));
|
||||
|
||||
$previewTable = new ContainerTable($form->getContainer(), 'font-preview', n2_('Preview'));
|
||||
|
||||
$previewTable->setFieldsetPositionEnd();
|
||||
|
||||
new Color($previewTable->getFieldsetLabel(), 'preview-background', false, 'ced3d5');
|
||||
|
||||
$form->render();
|
||||
}
|
||||
}
|
@ -0,0 +1,157 @@
|
||||
<?php
|
||||
|
||||
|
||||
namespace Nextend\Framework\Font\Sources\GoogleFonts;
|
||||
|
||||
use Nextend\Framework\Asset\AssetManager;
|
||||
use Nextend\Framework\Asset\Fonts\Google\Google;
|
||||
use Nextend\Framework\Asset\Js\Js;
|
||||
use Nextend\Framework\Font\AbstractFontSource;
|
||||
use Nextend\Framework\Font\FontSettings;
|
||||
use Nextend\Framework\Font\FontSources;
|
||||
use Nextend\Framework\Form\Container\ContainerRowGroup;
|
||||
use Nextend\Framework\Form\Element\OnOff;
|
||||
use Nextend\Framework\Form\Fieldset\FieldsetRow;
|
||||
use Nextend\Framework\Platform\Platform;
|
||||
use Nextend\Framework\Plugin;
|
||||
|
||||
|
||||
/*
|
||||
jQuery.getJSON('https://www.googleapis.com/webfonts/v1/webfonts?sort=alpha&key=AIzaSyBIzBtder0-ef5a6kX-Ri9IfzVwFu21PGw').done(function(data){
|
||||
var f = [];
|
||||
for(var i = 0; i < data.items.length; i++){
|
||||
f.push(data.items[i].family);
|
||||
}
|
||||
|
||||
var fontString='';
|
||||
f.forEach(function(font){
|
||||
fontString+= font+'\n';
|
||||
});
|
||||
|
||||
console.log(fontString);
|
||||
});
|
||||
*/
|
||||
|
||||
class GoogleFonts extends AbstractFontSource {
|
||||
|
||||
protected $name = 'google';
|
||||
|
||||
private static $fonts = array();
|
||||
|
||||
private static $styles = array();
|
||||
|
||||
public function __construct() {
|
||||
$lines = file(dirname(__FILE__) . '/families.csv', FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
|
||||
for ($i = 0; $i < count($lines); $i++) {
|
||||
self::$fonts[strtolower($lines[$i])] = $lines[$i];
|
||||
}
|
||||
self::$fonts['droid sans'] = 'Noto Sans';
|
||||
self::$fonts['droid sans mono'] = 'Roboto Mono';
|
||||
self::$fonts['droid serif'] = 'Noto Serif';
|
||||
}
|
||||
|
||||
public function getLabel() {
|
||||
return 'Google';
|
||||
}
|
||||
|
||||
public function renderFields($container) {
|
||||
|
||||
$row1 = new FieldsetRow($container, 'fonts-google-1');
|
||||
new OnOff($row1, 'google-enabled', n2_('Frontend'), 1, array(
|
||||
'tipLabel' => n2_('Frontend'),
|
||||
'tipDescription' => n2_('You can load Google Fonts on the frontend.'),
|
||||
'relatedFieldsOn' => array(
|
||||
'fontsgoogle-cache'
|
||||
)
|
||||
));
|
||||
new OnOff($row1, 'google-cache', n2_('Save fonts locally'), 0, array(
|
||||
'tipLabel' => n2_('Save fonts locally'),
|
||||
'tipDescription' => n2_('You can store the used Google Fonts on your server. This way all Google Fonts will load from your own domain.'),
|
||||
'tipLink' => 'https://smartslider.helpscoutdocs.com/article/1787-fonts#google'
|
||||
));
|
||||
new OnOff($row1, 'google-enabled-backend', n2_('Backend'), 1, array(
|
||||
'tipLabel' => n2_('Backend'),
|
||||
'tipDescription' => n2_('You can load Google Fonts in the backend.')
|
||||
));
|
||||
|
||||
$rowGroupStyle = new ContainerRowGroup($container, 'fonts-google-style', n2_('Style'));
|
||||
$rowStyle = $rowGroupStyle->createRow('fonts-google-style');
|
||||
new OnOff($rowStyle, 'google-style-100', '100', 0);
|
||||
new OnOff($rowStyle, 'google-style-100italic', '100 ' . n2_x('Italic', "Font style"), 0);
|
||||
new OnOff($rowStyle, 'google-style-200', '200', 0);
|
||||
new OnOff($rowStyle, 'google-style-200italic', '200 ' . n2_x('Italic', "Font style"), 0);
|
||||
new OnOff($rowStyle, 'google-style-300', '300', 1);
|
||||
new OnOff($rowStyle, 'google-style-300italic', '300 ' . n2_x('Italic', "Font style"), 0);
|
||||
new OnOff($rowStyle, 'google-style-400', n2_('Normal'), 1);
|
||||
new OnOff($rowStyle, 'google-style-400italic', n2_('Normal') . ' ' . n2_x('Italic', "Font style"), 0);
|
||||
new OnOff($rowStyle, 'google-style-500', '500', 0);
|
||||
new OnOff($rowStyle, 'google-style-500italic', '500 ' . n2_x('Italic', "Font style"), 0);
|
||||
new OnOff($rowStyle, 'google-style-600', '600', 0);
|
||||
new OnOff($rowStyle, 'google-style-600italic', '600 ' . n2_x('Italic', "Font style"), 0);
|
||||
new OnOff($rowStyle, 'google-style-700', '700', 0);
|
||||
new OnOff($rowStyle, 'google-style-700italic', '700 ' . n2_x('Italic', "Font style"), 0);
|
||||
new OnOff($rowStyle, 'google-style-800', '800', 0);
|
||||
new OnOff($rowStyle, 'google-style-800italic', '800 ' . n2_x('Italic', "Font style"), 0);
|
||||
new OnOff($rowStyle, 'google-style-900', '900', 0);
|
||||
new OnOff($rowStyle, 'google-style-900italic', '900 ' . n2_x('Italic', "Font style"), 0);
|
||||
}
|
||||
|
||||
public function getPath() {
|
||||
return dirname(__FILE__) . DIRECTORY_SEPARATOR . 'google' . DIRECTORY_SEPARATOR;
|
||||
}
|
||||
|
||||
public function onFontManagerLoad($force = false) {
|
||||
static $loaded;
|
||||
if (!$loaded || $force) {
|
||||
$loaded = true;
|
||||
$parameters = FontSettings::getPluginsData();
|
||||
|
||||
if ((!Platform::isAdmin() && $parameters->get('google-enabled', 1)) || (Platform::isAdmin() && $parameters->get('google-enabled-backend', 1))) {
|
||||
Google::$enabled = 1;
|
||||
|
||||
for ($i = 100; $i < 1000; $i += 100) {
|
||||
$this->addStyle($parameters, $i);
|
||||
$this->addStyle($parameters, $i . 'italic');
|
||||
}
|
||||
if (empty(self::$styles)) {
|
||||
self::$styles[] = '300';
|
||||
self::$styles[] = '400';
|
||||
}
|
||||
|
||||
Plugin::addAction('fontFamily', array(
|
||||
$this,
|
||||
'onFontFamily'
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function onFontManagerLoadBackend() {
|
||||
$parameters = FontSettings::getPluginsData();
|
||||
|
||||
if ($parameters->get('google-enabled-backend', 1)) {
|
||||
Js::addInline('new _N2.NextendFontServiceGoogle("' . implode(',', self::$styles) . '", ' . json_encode(self::$fonts) . ', ' . json_encode(AssetManager::$googleFonts->getLoadedFamilies()) . ');');
|
||||
}
|
||||
}
|
||||
|
||||
function addStyle($parameters, $weight) {
|
||||
if ($parameters->get('google-style-' . $weight, 0)) {
|
||||
self::$styles[] = $weight;
|
||||
}
|
||||
}
|
||||
|
||||
function onFontFamily($family) {
|
||||
$familyLower = strtolower($family);
|
||||
if (isset(self::$fonts[$familyLower])) {
|
||||
foreach (self::$styles as $style) {
|
||||
Google::addFont(self::$fonts[$familyLower], $style);
|
||||
}
|
||||
|
||||
return self::$fonts[$familyLower];
|
||||
}
|
||||
|
||||
return $family;
|
||||
}
|
||||
}
|
||||
|
||||
FontSources::registerSource(GoogleFonts::class);
|
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user