icons
This commit is contained in:
parent
b1e5c22101
commit
db02888776
@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<span class="icon" :class="sizeClass" @click="$emit('click', $event)">
|
||||
<img ref="img" :class="['iconic', 'iconic-fluid', size]" v-bind="extraIconAttributes" :style="{padding: svgPadding}" />
|
||||
<span class="icon" :class="sizeClass" @click="$emit('click', $event)" ref="container">
|
||||
|
||||
</span>
|
||||
</template>
|
||||
|
||||
@ -20,15 +20,101 @@
|
||||
import StarEmpty from "../iconic/svg/smart/star-empty";
|
||||
import X from "../iconic/svg/smart/x";
|
||||
|
||||
const iconicInstance = IconicJs({
|
||||
autoInjectSelector: null
|
||||
});
|
||||
const SVG_CACHE = {};
|
||||
let REMAP_COUNT = 0;
|
||||
|
||||
class IconData {
|
||||
constructor(url, dataAttributes) {
|
||||
this.url = url;
|
||||
constructor(svgData, dataAttributes) {
|
||||
this.svgData = svgData;
|
||||
this.dataAttributes = dataAttributes || {};
|
||||
this.dataAttributes['src'] = url;
|
||||
this.svgTemplate = null;
|
||||
}
|
||||
|
||||
getSvg() {
|
||||
if (this.svgTemplate === null) {
|
||||
const iconicName = this.svgData.attributes.class;
|
||||
|
||||
this.svgTemplate = SVG_CACHE[iconicName] || null;
|
||||
|
||||
if (this.svgTemplate === null) {
|
||||
this.svgTemplate = document.createElementNS("http://www.w3.org/2000/svg", "svg");
|
||||
SVG_CACHE[iconicName] = this.svgTemplate;
|
||||
|
||||
for (let attr in this.svgData.attributes) {
|
||||
this.svgTemplate.setAttribute(attr, this.svgData.attributes[attr]);
|
||||
}
|
||||
this.svgTemplate.innerHTML = this.svgData.content;
|
||||
|
||||
|
||||
// Find then prune the scripts
|
||||
const scripts = [...this.svgTemplate.querySelectorAll('script')];
|
||||
|
||||
scripts.filter(s => {
|
||||
let scriptType = s.getAttribute("type");
|
||||
return !scriptType || scriptType === 'application/ecmascript' || scriptType === 'application/javascript'
|
||||
}).forEach(s => {
|
||||
new Function(s.innerText || s.textContent)(window);
|
||||
this.svgTemplate.removeChild(s);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
const clone = this.svgTemplate.cloneNode(true);
|
||||
this.remapIds(clone);
|
||||
this.attachIconicApi(clone);
|
||||
for (let attr in this.dataAttributes) {
|
||||
clone.setAttribute(`data-${attr}`, this.dataAttributes[attr]);
|
||||
}
|
||||
return clone;
|
||||
}
|
||||
|
||||
remapIds(svg) {
|
||||
const iriElementsAndProperties = {
|
||||
'clipPath': ['clip-path'],
|
||||
'color-profile': ['color-profile'],
|
||||
'cursor': ['cursor'],
|
||||
'filter': ['filter'],
|
||||
'linearGradient': ['fill', 'stroke'],
|
||||
'marker': ['marker', 'marker-start', 'marker-mid', 'marker-end'],
|
||||
'mask': ['mask'],
|
||||
'pattern': ['fill', 'stroke'],
|
||||
'radialGradient': ['fill', 'stroke']
|
||||
};
|
||||
|
||||
REMAP_COUNT += 1;
|
||||
|
||||
let element, elementDefs, properties, currentId, newId;
|
||||
Object.keys(iriElementsAndProperties).forEach(function (key) {
|
||||
element = key;
|
||||
properties = iriElementsAndProperties[key];
|
||||
|
||||
elementDefs = svg.querySelectorAll('defs ' + element + '[id]');
|
||||
for (var i = 0, elementsLen = elementDefs.length; i < elementsLen; i++) {
|
||||
currentId = elementDefs[i].id;
|
||||
newId = currentId + '-' + REMAP_COUNT;
|
||||
|
||||
// All of the properties that can reference this element type
|
||||
var referencingElements;
|
||||
properties.forEach(function (property) {
|
||||
// :NOTE: using a substring match attr selector here to deal with IE "adding extra quotes in url() attrs"
|
||||
referencingElements = svg.querySelectorAll('[' + property + '*="' + currentId + '"]');
|
||||
for (var j = 0, referencingElementLen = referencingElements.length; j < referencingElementLen; j++) {
|
||||
referencingElements[j].setAttribute(property, 'url(#' + newId + ')');
|
||||
}
|
||||
});
|
||||
|
||||
elementDefs[i].id = newId;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
attachIconicApi(svg) {
|
||||
const key = svg.getAttribute("data-icon");
|
||||
const apis = window.iconicSmartIconApis;
|
||||
if (key && apis[key]) {
|
||||
const iconApi = apis[key](svg);
|
||||
for (let func in iconApi) svg[func] = iconApi[func]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -39,6 +125,43 @@
|
||||
}
|
||||
}
|
||||
|
||||
class IconicQueue {
|
||||
constructor(iconicInstance) {
|
||||
this.iconic = iconicInstance;
|
||||
this.updateQueue = [];
|
||||
this.isTimerRunning = false;
|
||||
}
|
||||
|
||||
processQueues() {
|
||||
if (this.updateQueue.length > 0) {
|
||||
console.log(`updating ${this.updateQueue.length}`);
|
||||
this.iconic.update(this.updateQueue);
|
||||
this.updateQueue.forEach(s => (s.style.visibility = null));
|
||||
this.updateQueue = [];
|
||||
}
|
||||
|
||||
this.isTimerRunning = false;
|
||||
}
|
||||
|
||||
ensureTimer() {
|
||||
if (!this.isTimerRunning) {
|
||||
this.isTimerRunning = true;
|
||||
setTimeout(() => this.processQueues());
|
||||
}
|
||||
}
|
||||
|
||||
updateSvg(svgElem) {
|
||||
this.updateQueue.push(svgElem);
|
||||
this.ensureTimer();
|
||||
}
|
||||
}
|
||||
|
||||
const iconicInstance = IconicJs({
|
||||
autoInjectSelector: "#notreal-noinjection"
|
||||
});
|
||||
|
||||
const iconicQueue = new IconicQueue(iconicInstance);
|
||||
|
||||
const iconMap = {
|
||||
'caret-bottom': new IconData(Caret, {direction: 'bottom'}),
|
||||
'caret-top': new IconData(Caret, {direction: 'top'}),
|
||||
@ -97,15 +220,6 @@
|
||||
return sizeMap[this.size];
|
||||
},
|
||||
|
||||
extraIconAttributes() {
|
||||
const attrs = {};
|
||||
|
||||
for (let attr in this.iconData.dataAttributes) {
|
||||
attrs[`data-${attr}`] = this.iconData.dataAttributes[attr];
|
||||
}
|
||||
return attrs;
|
||||
},
|
||||
|
||||
sizeClass() {
|
||||
return this.sizeData.bulmaIconClass;
|
||||
},
|
||||
@ -115,22 +229,42 @@
|
||||
}
|
||||
},
|
||||
|
||||
mounted() {
|
||||
const self = this;
|
||||
setTimeout(() => {
|
||||
iconicInstance.inject(this.$refs.img, {
|
||||
each: function(svg) { self.injectedSvg = svg; }
|
||||
methods: {
|
||||
insertSvg() {
|
||||
const parent = this.$refs.container;
|
||||
|
||||
while (parent.firstChild) {
|
||||
parent.removeChild(parent.firstChild);
|
||||
}
|
||||
|
||||
const svg = this.iconData.getSvg();
|
||||
this.injectedSvg = svg;
|
||||
|
||||
svg.style.padding = this.svgPadding;
|
||||
svg.style.visibility = "hidden";
|
||||
svg.classList.add("iconic-fluid");
|
||||
parent.appendChild(svg);
|
||||
|
||||
|
||||
setTimeout(() => {
|
||||
//svg.style.visibility = "visible";
|
||||
//iconicInstance.update(svg);
|
||||
iconicQueue.updateSvg(svg);
|
||||
});
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
updated() {
|
||||
if (this.injectedSvg) {
|
||||
for(let attr in this.extraIconAttributes) {
|
||||
this.injectedSvg.setAttribute(attr, this.extraIconAttributes[attr]);
|
||||
mounted() {
|
||||
let self = this;
|
||||
this.$watch(
|
||||
function() { return this.icon + this.size + this.padding },
|
||||
function() {
|
||||
this.insertSvg();
|
||||
},
|
||||
{
|
||||
immediate: true
|
||||
}
|
||||
iconicInstance.update(this.injectedSvg);
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3,9 +3,9 @@ const vue = require('./loaders/vue');
|
||||
const svg = require('./loaders/svg');
|
||||
|
||||
environment.loaders.append('vue', vue);
|
||||
//environment.loaders.prepend('svg', svg);
|
||||
environment.loaders.prepend('svg', svg);
|
||||
|
||||
//const fileLoader = environment.loaders.get('file');
|
||||
//fileLoader.exclude = /\.(svg)$/i;
|
||||
const fileLoader = environment.loaders.get('file');
|
||||
fileLoader.exclude = /\.(svg)$/i;
|
||||
|
||||
module.exports = environment;
|
||||
|
@ -1,10 +1,18 @@
|
||||
const path = require("path");
|
||||
|
||||
module.exports = {
|
||||
test: /\.svg$/,
|
||||
use: [{
|
||||
loader: 'url-loader',
|
||||
options: {
|
||||
limit: 10000
|
||||
}
|
||||
loader: path.join(__dirname, 'svg_loader.js')
|
||||
}]
|
||||
};
|
||||
|
||||
// module.exports = {
|
||||
// test: /\.svg$/,
|
||||
// use: [{
|
||||
// loader: 'url-loader',
|
||||
// options: {
|
||||
// limit: 10000
|
||||
// }
|
||||
// }]
|
||||
// };
|
||||
|
27
config/webpack/loaders/svg_loader.js
Normal file
27
config/webpack/loaders/svg_loader.js
Normal file
@ -0,0 +1,27 @@
|
||||
module.exports = function(content) {
|
||||
this.cacheable && this.cacheable();
|
||||
|
||||
var match = content.match(/<svg([^>]+)+>([\s\S]+)<\/svg>/i);
|
||||
var attrs = {};
|
||||
|
||||
if (match) {
|
||||
attrs = match[1];
|
||||
if (attrs) {
|
||||
attrs = attrs.match(/([\w-:]+)(=)?("[^<>"]*"|'[^<>']*'|[\w-:]+)/g)
|
||||
.reduce(function(obj, attr){
|
||||
var split = attr.split('=');
|
||||
var name = split[0];
|
||||
var value = true;
|
||||
if (split && split[1]) {
|
||||
value = split[1].replace(/['"]/g, '');
|
||||
}
|
||||
obj[name] = value;
|
||||
return obj;
|
||||
}, {})
|
||||
}
|
||||
|
||||
content = match[2] || '';
|
||||
};
|
||||
|
||||
return "module.exports = " + JSON.stringify({attributes: attrs, content: content});
|
||||
};
|
@ -3,21 +3,50 @@ namespace :dev do
|
||||
desc 'Run both rails server and webpack dev server'
|
||||
task :run do
|
||||
|
||||
pids = []
|
||||
|
||||
pids << fork do
|
||||
rails_pid = fork do
|
||||
exec 'rails s'
|
||||
end
|
||||
|
||||
pids << fork do
|
||||
webpack_pid = fork do
|
||||
exec 'bin/webpack-dev-server'
|
||||
end
|
||||
|
||||
begin
|
||||
Process.wait
|
||||
rescue SignalException
|
||||
puts 'shutting down...'
|
||||
pids.each { |pid| Process.kill("SIGINT", pid) }
|
||||
running = true
|
||||
shutdown = false
|
||||
shutdown_start = nil
|
||||
|
||||
Signal.trap('SIGINT') do
|
||||
shutdown = true
|
||||
end
|
||||
|
||||
while running
|
||||
rails_check ||= Process.waitpid(rails_pid, Process::WNOHANG)
|
||||
webpack_check ||= Process.waitpid(webpack_pid, Process::WNOHANG)
|
||||
running = rails_check.nil? || webpack_check.nil?
|
||||
|
||||
if shutdown
|
||||
if shutdown_start.nil?
|
||||
puts "Shutting down..."
|
||||
shutdown_start = Time.now
|
||||
#Process.kill("SIGINT", rails_pid) rescue Errno::ESRCH
|
||||
#Process.kill("SIGINT", webpack_pid) rescue Errno::ESRCH
|
||||
end
|
||||
|
||||
if (Time.now - shutdown_start) > 5
|
||||
if rails_check.nil?
|
||||
puts "Force killing rails..."
|
||||
Process.kill("KILL", rails_pid)
|
||||
end
|
||||
|
||||
if webpack_check.nil?
|
||||
puts "Force killing webpack..."
|
||||
Process.kill("KILL", webpack_pid)
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
sleep 0.25
|
||||
end
|
||||
|
||||
end
|
||||
|
Loading…
Reference in New Issue
Block a user