summaryrefslogtreecommitdiffstats
path: root/src/attribute-rel-svg.cpp
blob: 8329d3fc619b69c776c2ea27cce1fa7b930a4052 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
// SPDX-License-Identifier: GPL-2.0-or-later
/** @file
 * TODO: insert short description here
 *//*
 * Authors: see git history
 *
 * Copyright (C) 2018 Authors
 * Released under GNU GPL v2+, read the file 'COPYING' for more information.
 */
/*
 * attribute-rel-svg.cpp
 *
 *  Created on: Jul 25, 2011
 *      Author: abhishek
 */

/** \class SPAttributeRelSVG
 *
 * SPAttributeRelSVG class stores the mapping of element->attribute
 * relationship and provides a static function to access that
 * mapping indirectly(only reading).
 */

#include <fstream>
#include <sstream>

#include "attribute-rel-svg.h"

#include "io/resource.h"
#include "path-prefix.h"
#include "preferences.h"

SPAttributeRelSVG * SPAttributeRelSVG::instance = nullptr;
bool SPAttributeRelSVG::foundFile = false;

/*
 * This function returns true if element is an SVG element.
 */
bool SPAttributeRelSVG::isSVGElement(Glib::ustring element)
{
    if (SPAttributeRelSVG::instance == nullptr) {
        SPAttributeRelSVG::instance = new SPAttributeRelSVG();
    }

    // Always valid if data file not found!
    if( !foundFile ) return true;

    // Strip off "svg:" from the element's name
    Glib::ustring temp = element;
    if ( temp.find("svg:") != std::string::npos ) {
        temp.erase( temp.find("svg:"), 4 );
    }

    return (SPAttributeRelSVG::instance->attributesOfElements.count(temp) > 0);
}

/*
 * This functions checks whether an element -> attribute pair is allowed or not
 */
bool SPAttributeRelSVG::findIfValid(Glib::ustring attribute, Glib::ustring element)
{
    if (SPAttributeRelSVG::instance == nullptr) {
        SPAttributeRelSVG::instance = new SPAttributeRelSVG();
    }

    // Always valid if data file not found!
    if( !foundFile ) return true;

    // Strip off "svg:" from the element's name
    Glib::ustring temp = element;
    if ( temp.find("svg:") != std::string::npos ) {
        temp.erase( temp.find("svg:"), 4 );
    }
    
    // Check for attributes with -, role, aria etc. to allow for more accessibility
    // clang-format off
    if (attribute[0] == '-'
        || attribute.substr(0,4) == "role"
        || attribute.substr(0,4) == "aria"
        || attribute.substr(0,5) == "xmlns"
        || attribute.substr(0,9) == "inkscape:"
        || attribute.substr(0,9) == "sodipodi:"
        || attribute.substr(0,4) == "rdf:"
        || attribute.substr(0,3) == "cc:"
        || attribute.substr(0,4) == "ns1:"  // JessyInk
        || (SPAttributeRelSVG::instance->attributesOfElements[temp].find(attribute)
            != SPAttributeRelSVG::instance->attributesOfElements[temp].end()) ) {
    // clang-format on
        return true;
    } else {
        //g_warning( "Invalid attribute: %s used on <%s>", attribute.c_str(), element.c_str() );
        return false;
    }
}

/*
 * One timer singleton constructor, to load the element -> attributes data
 * into memory.
 */
SPAttributeRelSVG::SPAttributeRelSVG()
{
    std::fstream f;
    
    // Read data from standard path
    using namespace Inkscape::IO::Resource;
    auto filepath = get_path_string(SYSTEM, ATTRIBUTES, "svgprops");

    f.open(filepath.c_str(), std::ios::in);

    if (!f.is_open()) {
        // Display warning for file not open
        g_warning("Could not open the data file for XML attribute-element map construction: %s", filepath.c_str());
        f.close();
        return ;
    }

    foundFile = true;

    while (!f.eof()){
        std::stringstream ss;
        std::string s;

        std::getline(f,s,'"');
        std::getline(f,s,'"');
        if(s.size() > 0 && s[0] != '\n'){
            std::string prop = s;
            getline(f,s);
            ss << s;

            while(std::getline(ss,s,'"')){
                std::string element;
                std::getline(ss,s,'"');
                element = s;
                attributesOfElements[element].insert(prop);
            }
        }
    }
    
    f.close();
}

/*
  Local Variables:
  mode:c++
  c-file-style:"stroustrup"
  c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
  indent-tabs-mode:nil
  fill-column:99
  End:
*/
// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :