mirror of
https://github.com/ijprest/keyboard-layout-editor
synced 2024-11-13 07:10:41 +00:00
Parse user-defined glyphs in CSS
This commit is contained in:
parent
0bf77c0d8b
commit
900caca4a7
2
kb.html
2
kb.html
@ -88,6 +88,8 @@ Nav Bar / Header
|
||||
<a class="dropdown-toggle" dropdown-toggle><i class="fa fa-font"></i> Character Picker <b class="caret"></b></a>
|
||||
<ul class="dropdown-menu">
|
||||
<li ng-repeat="picker in pickers"><a ng-click="loadCharacterPicker(picker)" href="#">{{picker.name}}</a></li>
|
||||
<li class="divider"></li>
|
||||
<li><a ng-click="loadCharacterPicker(null)" href="#">User-Defined Glyphs</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
|
59
kb.js
59
kb.js
@ -214,6 +214,15 @@
|
||||
$scope.kbHeight = bottom;
|
||||
};
|
||||
|
||||
function updateFromCss(css) {
|
||||
var rules = $cssParser.parse(css);
|
||||
$scope.customGlyphs = $renderKey.getGlyphsFromRules(rules); // glyphs first, before rules are modified!
|
||||
$scope.customStyles = $sce.trustAsHtml($renderKey.sanitizeCssRules(rules));
|
||||
if($scope.picker.sentinel === userGlyphsSentinel) {
|
||||
$scope.picker.glyphs = $scope.customGlyphs;
|
||||
}
|
||||
}
|
||||
|
||||
// Given a key, generate the HTML needed to render it
|
||||
function renderKey(key) {
|
||||
key.html = $sce.trustAsHtml($renderKey.html(key,$sanitize));
|
||||
@ -226,7 +235,7 @@
|
||||
renderKey(key);
|
||||
});
|
||||
$scope.meta = angular.copy($scope.keyboard.meta);
|
||||
$scope.customStyles = $sce.trustAsHtml($renderKey.renderCSS($scope.meta.css));
|
||||
updateFromCss($scope.meta.css || '');
|
||||
};
|
||||
|
||||
function updateSerialized() {
|
||||
@ -584,46 +593,23 @@
|
||||
$scope.calcKbHeight();
|
||||
};
|
||||
|
||||
function parsePickerCSS(css) {
|
||||
// Parse the CSS
|
||||
var rules = $cssParser.parse(css);
|
||||
|
||||
// Find rules that look like the base slyph-set definition
|
||||
var classes = [];
|
||||
rules.forEach(function(rule) {
|
||||
if(!rule.name && rule.selector.length === 1 && rule.selector[0].match(/^\.[a-zA-Z0-9]+$/)) {
|
||||
classes.push(rule.selector[0].substring(1));
|
||||
}
|
||||
});
|
||||
|
||||
// Find rules that look like glyphs
|
||||
var glyphs = [];
|
||||
rules.forEach(function(rule) {
|
||||
if(!rule.name && rule.selector.length === 1) {
|
||||
var matches = rule.selector[0].match(/^\.([a-zA-Z0-9]+)-([-a-zA-Z0-9]+)\:(before|after)$/);
|
||||
if(matches) {
|
||||
var theClass = classes.indexOf(matches[1]);
|
||||
if(theClass != -1) {
|
||||
var glyph = { name: matches[2], html: "<i class='" + classes[theClass] + " " + matches[1]+"-"+matches[2] +"'></i>" };
|
||||
glyphs.push(glyph);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
glyphs.sort(function(a,b) { return a.name.localeCompare(b.name); });
|
||||
return glyphs;
|
||||
}
|
||||
|
||||
var userGlyphsSentinel = {};
|
||||
$scope.loadCharacterPicker = function(picker) {
|
||||
$scope.picker = picker;
|
||||
$scope.picker = picker || {
|
||||
name: "User-Defined Glyphs",
|
||||
glyphs: $scope.customGlyphs,
|
||||
href: "https://github.com/ijprest/keyboard-layout-editor/wiki/Custom-Styles",
|
||||
description: "This list will show any glyphs defined in your layout's 'Custom Styles' tab. See the Commodore VIC-20 sample layout for an example.",
|
||||
sentinel: userGlyphsSentinel
|
||||
};
|
||||
$scope.palette = {}; // turn off the palette
|
||||
$scope.pickerFilter = '';
|
||||
$scope.pickerSelection = {};
|
||||
|
||||
// Load the CSS if necessary
|
||||
if(picker.css && !picker.glyphs) {
|
||||
$http.get(picker.css).success(function(css) {
|
||||
picker.glyphs = parsePickerCSS(css);
|
||||
if($scope.picker.css && !$scope.picker.glyphs) {
|
||||
$http.get($scope.picker.css).success(function(css) {
|
||||
$scope.picker.glyphs = $renderKey.getGlyphsFromRules($cssParser.parse(css));
|
||||
});
|
||||
}
|
||||
};
|
||||
@ -763,6 +749,7 @@
|
||||
|
||||
$scope.customStylesException = "";
|
||||
$scope.customStyles = "";
|
||||
$scope.customGlyphs = [];
|
||||
$scope.updateCustomStyles = function() {
|
||||
if(customStylesTimer) {
|
||||
$timeout.cancel(customStylesTimer);
|
||||
@ -771,7 +758,7 @@
|
||||
try {
|
||||
$scope.customStylesException = "";
|
||||
transaction("customstyles", function() {
|
||||
$scope.customStyles = $sce.trustAsHtml($renderKey.renderCSS($scope.meta.css));
|
||||
updateFromCss($scope.meta.css);
|
||||
$scope.updateMeta('css');
|
||||
});
|
||||
} catch(e) {
|
||||
|
98
render.js
98
render.js
@ -199,45 +199,69 @@ var $renderKey = (typeof(exports) !== 'undefined') ? exports : {};
|
||||
});
|
||||
};
|
||||
|
||||
$renderKey.renderCSS = function(css) {
|
||||
if(css) {
|
||||
var rules = $cssParser.parse(css);
|
||||
if(rules) {
|
||||
// Sanitize the CSS
|
||||
rules.forEach(function(rule) {
|
||||
if(!rule.name) {
|
||||
for(var i = 0; i < rule.selector.length; ++i) {
|
||||
rule.selector[i] = "#keyboard .keycap " + rule.selector[i];
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
// Re-stringify the sanitized CSS
|
||||
css = "";
|
||||
rules.forEach(function(rule) {
|
||||
if(!rule.name) {
|
||||
css += rule.selector.join(', ') + " { ";
|
||||
if(rule.decls) {
|
||||
for(var i = 0; i < rule.decls.length; ++i) {
|
||||
css += rule.decls[i][0] + ": " + rule.decls[i][1] + "; ";
|
||||
}
|
||||
}
|
||||
css += "}\n";
|
||||
} else {
|
||||
var ok = (rule.name === "@font-face")
|
||||
|| (rule.name === "@import" && !rule.content && rule.selector.match(/^url\(http:\/\/fonts.googleapis.com\/css\?family=[^\)]+\)$/));
|
||||
if(ok) {
|
||||
css += rule.name;
|
||||
if(rule.selector) css += ' ' + rule.selector;
|
||||
if(rule.content) css += '{ ' + rule.content + ' }\n';
|
||||
else css += ';\n';
|
||||
}
|
||||
}
|
||||
});
|
||||
return css;
|
||||
$renderKey.getGlyphsFromRules = function(rules) {
|
||||
// Find rules that look like the base slyph-set definition
|
||||
var classes = [];
|
||||
rules.forEach(function(rule) {
|
||||
if(!rule.name && rule.selector.length === 1 && rule.selector[0].match(/^\.[a-zA-Z0-9]+$/)) {
|
||||
classes.push(rule.selector[0].substring(1));
|
||||
}
|
||||
});
|
||||
|
||||
// Find rules that look like glyphs
|
||||
var glyphs = [];
|
||||
rules.forEach(function(rule) {
|
||||
if(!rule.name && rule.selector.length === 1) {
|
||||
var matches = rule.selector[0].match(/^\.([a-zA-Z0-9]+)-([-a-zA-Z0-9]+)\:(before|after)$/);
|
||||
if(matches) {
|
||||
var theClass = classes.indexOf(matches[1]);
|
||||
if(theClass != -1) {
|
||||
var glyph = { name: matches[2], html: "<i class='" + classes[theClass] + " " + matches[1]+"-"+matches[2] +"'></i>" };
|
||||
glyphs.push(glyph);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
glyphs.sort(function(a,b) { return a.name.localeCompare(b.name); });
|
||||
return glyphs;
|
||||
}
|
||||
|
||||
$renderKey.sanitizeCssRules = function(rules) {
|
||||
if(rules) {
|
||||
// Sanitize the CSS
|
||||
rules.forEach(function(rule) {
|
||||
if(!rule.name) {
|
||||
for(var i = 0; i < rule.selector.length; ++i) {
|
||||
rule.selector[i] = "#keyboard .keycap " + rule.selector[i] + ", #glyphScroller " + rule.selector[i];
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
// Re-stringify the sanitized CSS
|
||||
var css = "";
|
||||
rules.forEach(function(rule) {
|
||||
if(!rule.name) {
|
||||
css += rule.selector.join(', ') + " { ";
|
||||
if(rule.decls) {
|
||||
for(var i = 0; i < rule.decls.length; ++i) {
|
||||
css += rule.decls[i][0] + ": " + rule.decls[i][1] + "; ";
|
||||
}
|
||||
}
|
||||
css += "}\n";
|
||||
} else {
|
||||
var ok = (rule.name === "@font-face")
|
||||
|| (rule.name === "@import" && !rule.content && rule.selector.match(/^url\(http:\/\/fonts.googleapis.com\/css\?family=[^\)]+\)$/));
|
||||
if(ok) {
|
||||
css += rule.name;
|
||||
if(rule.selector) css += ' ' + rule.selector;
|
||||
if(rule.content) css += '{ ' + rule.content + ' }\n';
|
||||
else css += ';\n';
|
||||
}
|
||||
}
|
||||
});
|
||||
return css;
|
||||
}
|
||||
return "";
|
||||
};
|
||||
}
|
||||
|
||||
}());
|
||||
|
Loading…
Reference in New Issue
Block a user